为啥 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_namessys.modules 来检查这一点。 @JimFasarakis-Hilliard 问题是为什么itertools(和我测试过的其他一些模块)在被导入到 Python 3 而不是 Python 2 之前在 sys.modules 【参考方案1】:

他们已经被进口了,只是不是你进口的。解释器启动的确切部分导致模块被加载是不重要的实现细节,但如果需要,您可以跟踪可能的路径。比如itertoolsreprlib导入

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' 中没有导入的模块?的主要内容,如果未能解决你的问题,请参考以下文章

python 多模块文件共享变量

python导入模块时的执行顺序

MLPerf Nvidia 基准测试失败:命令“cat /sys/module/mlx5_core/version”返回非零退出状态 1

迭代python中的不同函数

14.模块的使用,包,及程序开发规范

急求!!!在python语言中,列表中能否包含元组,为啥?元组中能否包含列表,为啥? 谢谢大神