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() 函数。例如,如果模块已更改,则可能是这样。 如果只使用ReallyBigLibfrom 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 是不是会在多次导入模块时优化模块?的主要内容,如果未能解决你的问题,请参考以下文章

模块的导入方法

Python模块与包的概念

Python之模块和包

python第十天学习总结

python学习_day27_模块与包

模块