python 是不是会在多次导入模块时优化模块?
Posted
技术标签:
【中文标题】python 是不是会在多次导入模块时优化模块?【英文标题】:Does python optimize modules when they are imported multiple times?python 是否会在多次导入模块时优化模块? 【发布时间】:2008-11-17 16:21:43 【问题描述】:如果您的代码的某个子模块加载了一个大模块,那么从该命名空间引用该模块而不是再次导入它有什么好处?
例如: 我有一个模块MyLib,它广泛使用了ReallyBigLib。如果我有导入 MyLib 的代码,我应该像这样挖掘模块吗
import MyLib
ReallyBigLib = MyLib.SomeModule.ReallyBigLib
或者只是
import MyLib
import ReallyBigLib
【问题讨论】:
【参考方案1】:Python 模块可以被视为单例...无论您导入它们多少次,它们都只会被初始化一次,所以最好这样做:
import MyLib
import ReallyBigLib
import 声明的相关文档:
https://docs.python.org/2/reference/simple_stmts.html#the-import-statement
一旦知道模块的名称(除非另有说明,术语“模块”将指包和模块),就可以开始搜索模块或包。检查的第一个地方是 sys.modules,之前已导入的所有模块的缓存。如果在那里找到该模块,则在导入的步骤 (2) 中使用它。
导入的模块缓存在sys.modules:
这是一个将模块名称映射到已经加载的模块的字典。这可以被操纵以强制重新加载模块和其他技巧。请注意,从该字典中删除模块与在相应模块对象上调用 reload() 不同。
【讨论】:
谢谢,我可以发誓我在某处读到过这篇文章,但找不到确认 但是,如果要重新导入模块,则可以使用 reload() 函数。例如,如果模块已更改,则可能是这样。 如果只使用ReallyBigLib
,from MyLib.SomeModule import ReallyBigLib
不是更好吗?【参考方案2】:
正如其他人所指出的,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 的一大优点是如何将所有内容都转化为在命名空间中执行脚本。
【讨论】:
“Python 的优点之一是一切都可以转移到在命名空间中执行脚本。”除了 Python 从 C 代码编译的二进制文件之外? 用简化的 Python 记录二进制文件的逻辑会很有趣。理论上,文档可以执行来证明 C 代码。【参考方案3】:它没有实质性的区别。如果已经加载了大模块,则第二个示例中的第二个导入除了将“ReallyBigLib”添加到当前命名空间之外什么都不做。
【讨论】:
【参考方案4】:警告:Python 不保证模块不会被初始化两次。 我遇到过这样的问题。见讨论: http://code.djangoproject.com/ticket/8193
【讨论】:
对于 2018 年之后阅读本文的任何人:根据链接,问题似乎已得到解决。【参考方案5】:导入模块的内部注册表是sys.modules
字典,它将模块名称映射到模块对象。您可以在那里查看当前导入的所有模块。
您还可以通过使用sys.modules
来获取一些有用的技巧(如果需要) - 例如将您自己的对象添加为可以由其他模块导入的伪模块。
【讨论】:
【参考方案6】:在性能方面是相同的。 Python 中还没有 JIT 编译器。
【讨论】:
以上是关于python 是不是会在多次导入模块时优化模块?的主要内容,如果未能解决你的问题,请参考以下文章