如果您的代码的某个子模块加载了一个大模块,那么从该命名空间引用该模块而不是再次导入它有什么好处?
例如:我有一个模块MyLib,它广泛使用了ReallyBigLib。如果我有导入 MyLib 的代码,我应该像这样挖掘模块吗
import MyLib
ReallyBigLib = MyLib.SomeModule.ReallyBigLib
要不就
import MyLib
import ReallyBigLib
如果您的代码的某个子模块加载了一个大模块,那么从该命名空间引用该模块而不是再次导入它有什么好处?
例如:我有一个模块MyLib,它广泛使用了ReallyBigLib。如果我有导入 MyLib 的代码,我应该像这样挖掘模块吗
import MyLib
ReallyBigLib = MyLib.SomeModule.ReallyBigLib
要不就
import MyLib
import ReallyBigLib
Python模块可以被视为单例......无论您导入它们多少次,它们都只会被初始化一次,所以最好这样做:
import MyLib
import ReallyBigLib
进口声明的相关文件:
https://docs.python.org/2/reference/simple_stmts.html#the-import-statement
一旦知道模块的名称(除非另有说明,术语“模块”将指包和模块),就可以开始搜索模块或包。检查的第一个地方是 sys.modules,之前已导入的所有模块的缓存。如果在那里找到模块,则在导入的步骤 (2) 中使用它。
导入的模块缓存在sys.modules 中:
这是一个将模块名称映射到已经加载的模块的字典。这可以被操纵以强制重新加载模块和其他技巧。请注意,从该字典中删除模块与在相应模块对象上调用 reload() 不同。
正如其他人指出的那样,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 的优点之一是如何将一切都转移到在命名空间中执行脚本。
它没有实质性的区别。如果已经加载了大模块,则第二个示例中的第二个导入除了将“ReallyBigLib”添加到当前命名空间之外什么都不做。
警告:Python 不保证模块不会被初始化两次。我遇到过这样的问题。见讨论: http ://code.djangoproject.com/ticket/8193
导入模块的内部注册表是sys.modules
字典,它将模块名称映射到模块对象。您可以在那里查看当前导入的所有模块。
您还可以通过猴子来获取一些有用的技巧(如果需要)sys.modules
- 例如将您自己的对象添加为可以由其他模块导入的伪模块。
在性能方面是相同的。Python 中还没有 JIT 编译器。