当多次导入模块时,python 是否会进行优化?
- 2025-02-18 09:25:00
- admin 原创
- 73
问题描述:
如果您的代码的某些子模块加载了一个大型模块,那么从该命名空间引用该模块而不是再次导入它有什么好处吗?
例如:我有一个模块 MyLib,它大量使用了 ReallyBigLib。如果我有导入 MyLib 的代码,我是否应该像这样挖出该模块
import MyLib
ReallyBigLib = MyLib.SomeModule.ReallyBigLib
或者只是
import MyLib
import ReallyBigLib
解决方案 1:
Python 模块可以被视为单例……无论你导入它们多少次,它们都只会初始化一次,因此最好这样做:
import MyLib
import ReallyBigLib
进口声明的相关文件:
https://docs.python.org/2/reference/simple_stmts.html#the-import-statement
一旦知道了模块的名称(除非另有说明,术语“模块”将指代包和模块),就可以开始搜索模块或包。首先检查的是 sys.modules,这是之前已导入的所有模块的缓存。如果在那里找到模块,则在导入的步骤 (2) 中使用它。
导入的模块缓存在sys.modules中:
这是一个将模块名称映射到已加载模块的字典。可以对其进行操作以强制重新加载模块和其他技巧。请注意,从此字典中删除模块与在相应的模块对象上调用 reload() 不同。
解决方案 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 的优点之一就是一切都可以归结为在命名空间中执行脚本。
解决方案 3:
这没什么实质性的区别。如果大模块已经加载,则第二个示例中的第二次导入除了将“ReallyBigLib”添加到当前命名空间外,不会执行任何操作。
解决方案 4:
警告:Python 不保证模块不会被初始化两次。我曾遇到过这样的问题。请参阅讨论:
http ://code.djangoproject.com/ticket/8193
解决方案 5:
导入模块的内部注册表是字典sys.modules
,它将模块名称映射到模块对象。您可以在那里查看当前导入的所有模块。
您还可以通过一些小技巧(如果需要)来使用一些有用的技巧sys.modules
- 例如将您自己的对象添加为可以被其他模块导入的伪模块。
解决方案 6:
性能方面也一样。Python 中还没有 JIT 编译器。
扫码咨询,免费领取项目管理大礼包!