2008-11-17 65 views
34

如果一个大模块被代码的某个子模块加载,那么从该名称空间引用模块而不是再次导入它有什么好处?python会在多次导入模块时优化模块吗?

例如: 我有一个模块MyLib,它广泛使用了ReallyBigLib。如果我有进口MyLib中的代码,我应该挖掘模块从像这样

import MyLib 
ReallyBigLib = MyLib.SomeModule.ReallyBigLib 

或只是

import MyLib 
import ReallyBigLib 

回答

46

Python模块可被视为单身......无论多少次,你将它们导入他们得到初始化只有一次,所以最好做到:

import MyLib 
import ReallyBigLib 

相关文档的import语句:

https://docs.python.org/2/reference/simple_stmts.html#the-import-statement

一旦模块的名称是已知的(除非另有规定,术语“模块”指的两个包和模块),搜索吨他可以开始模块或包装。检查的第一个地方是sys.modules,这是先前导入的所有模块的缓存。如果找到该模块,则在步骤(2)中使用该模块。

导入模块被缓存在sys.modules

这是模块的名称映射到一个已加载模块的字典。这可以被操纵来强制重新加载模块和其他技巧。请注意,从该字典中删除模块与在相应的模块对象上调用reload()不同。

+0

谢谢, 我可以发誓我读了这个地方,但我找不到它确认 – JimB 2008-11-17 16:41:13

+2

但是,如果你想重新导入模块,那么你可以使用reload()函数。例如,这可能是模块发生了变化。 – 2008-11-17 22:43:24

0

这是相同的performancewise。 Python中没有JIT编译器。

+0

现在我们有[PyPy](http://pypy.org/),其中包括基于llvm的JIT。 – BobC 2014-04-10 18:16:09

7

它没有实质区别。如果大模块已经被加载,则第二个示例中的第二个导入除了将“ReallyBigLib”添加到当前名称空间之外什么都不做。

20

正如其他人指出的那样,Python维护一个已导入的所有模块的内部列表。当您第一次导入模块时,模块(脚本)将在其自己的名称空间中执行,直到结束,内部列表被更新,并且在导入语句后继续执行。

试试这个代码:

# module/file a.py 
    print "Hello from a.py!" 
    import b 

    # module/file b.py 
    print "Hello from b.py!" 
    import a 

没有循环:只有一个缓存查找。

>>> import b 
Hello from b.py! 
Hello from a.py! 
>>> import a 
>>> 

Python的美丽之处在于,每个东西都是如何执行命名空间中的脚本的。

3

导入模块的内部注册表是sys.modules字典,它将模块名称映射到模块对象。您可以在那里查看当前导入的所有模块。

您也可以通过与sys.modules进行联系来获取一些有用的技巧(例如,如果需要) - 例如将您自己的对象添加为可由其他模块导入的伪模块。