python是否在多次导入时优化模块?

时间:2008-11-17 16:21:43

标签: python python-import

如果代码的某个子模块加载了大型模块,那么从该命名空间引用该模块而不是再次导入该模块是否有任何好处?

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

import MyLib
ReallyBigLib = MyLib.SomeModule.ReallyBigLib

或只是

import MyLib
import ReallyBigLib

6 个答案:

答案 0 :(得分:64)

Python模块可以被视为单例......无论你导入它们多少次,它们只被初始化一次,所以最好这样做:

import MyLib
import ReallyBigLib

有关进口声明的相关文件:

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

  

一旦知道模块的名称(除非另有说明,术语“模块”将指代包和模块),搜索模块或包可以开始。检查的第一个位置是sys.modules,它是先前导入的所有模块的缓存。如果在那里找到该模块,那么它将在导入的步骤(2)中使用。

导入的模块缓存在sys.modules

  

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

答案 1 :(得分:35)

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

试试这段代码:

   # 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的优点之一就是如何将所有内容转移到在命名空间中执行脚本。

答案 2 :(得分:8)

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

答案 3 :(得分:6)

警告:Python不保证模块不会被初始化两次。 我纠结了这个问题。见讨论: http://code.djangoproject.com/ticket/8193

答案 4 :(得分:3)

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

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

答案 5 :(得分:0)

性能相同。 Python中还没有JIT编译器。