为啥 Python 3 的 'sys.modules' 中没有导入的模块?
Posted
技术标签:
【中文标题】为啥 Python 3 的 \'sys.modules\' 中没有导入的模块?【英文标题】:Why are modules that haven't been imported in 'sys.modules' in Python 3?为什么 Python 3 的 'sys.modules' 中没有导入的模块? 【发布时间】:2017-07-07 10:33:41 【问题描述】:我正在阅读how to check if a python module has been imported 并且说明似乎很清楚,请检查sys.modules
中的模块。这正如我在 Python 2 中所期望的那样工作,但不适用于 Python 3(3.5 和 3.6 测试)。例如:
Python 3.6
>>> import sys
>>> 'itertools' in sys.modules
True
Python 2.7
>>> import sys
>>> 'itertools' in sys.modules
False
我注意到,itertools
在 Python 3 sys.modules dict
(<module 'itertools' (built-in)>
) 中被描述为“内置”,而不是在 Python 2 中,所以也许这就是它在导入之前在 sys.modules
中的原因,但它是not listed as a built-in。无论如何,由于itertools
仍然需要在 Python 3 中导入,我将不胜感激。
【问题讨论】:
如果您已经导入的任何模块需要导入它们自己的模块,这些模块将显示为已加载。也许 Python 3 中引入了 Python 2 中不存在的依赖项。即使加载了一个模块,您也需要import
使其在当前范围内可用。
我想你自己已经回答了这个问题:如果itertools
已成为内置函数,它将在解释器启动时立即加载。
是为什么itertools
需要导入的问题,或者为什么它存在并且没有在文档中这样列出?
@ForceBru:不,内置模块并非在启动时全部加载。您可以通过在新的解释器中比较 sys.builtin_module_names
和 sys.modules
来检查这一点。
@JimFasarakis-Hilliard 问题是为什么itertools
(和我测试过的其他一些模块)在被导入到 Python 3 而不是 Python 2 之前在 sys.modules
中
【参考方案1】:
他们已经被进口了,只是不是你进口的。解释器启动的确切部分导致模块被加载是不重要的实现细节,但如果需要,您可以跟踪可能的路径。比如itertools
被reprlib
导入
from itertools import islice
由functools
导入:
from reprlib import recursive_repr
由types
导入:
import functools as _functools
由importlib
导入:
import types
它在解释器启动时被引导,因为它是大部分导入实现的地方。
【讨论】:
太好了,谢谢权威解答。所以解释器导入itertools
(和其他模块,如os
)但没有将它们添加到globals()
,所以它们无法访问?
@Chris_Rands:它遵循正常的导入规则。如果模块foo
执行import bar
,则该导入仅使bar
模块可用于foo
模块。每个想要使用模块的人都需要自己导入它。
这就是为什么你在Py 2
中找不到它的原因我猜,当导入机制仍在C
中实现并且(显然)没有间接导入itertools
时。 【参考方案2】:
似乎在 Python 3 中,itertools 扩展实际上是编译到主要的 Python 二进制文件中,这与 Python 2 不同。如果你这样做了
import sys
然后是一个
'itertools' in sys.builtin_module_names
>> True
很清楚。在 Python 2.x 控制台中执行完全相同的步骤会生成 False
。
As per the docs、builtin_module_names
由'编译到此 Python 解释器中的模块'组成。
【讨论】:
问题是为什么这是,而不是它只是。 @JimFasarakis-Hilliard 对于“为什么 itertools 在被导入 Python 3 而不是 Python 2 之前在 sys.modules 中”的答案是“因为它是一个内置的,通过它在builtin_module_names
"中的存在来证明。
虽然模块确实被编译成 Python,但这些模块仍然需要在某个地方通过导入进行初始化和加载,然后才能显示在 sys.modules
中。
我投了反对票,因为这个答案暗示itertools
在启动时加载的原因是因为它是内置的。并非所有内置模块都在解释器启动时加载。以上是关于为啥 Python 3 的 'sys.modules' 中没有导入的模块?的主要内容,如果未能解决你的问题,请参考以下文章
MLPerf Nvidia 基准测试失败:命令“cat /sys/module/mlx5_core/version”返回非零退出状态 1