gpt4 book ai didi

python - 为什么 sys.modules 中有虚拟模块?

转载 作者:IT老高 更新时间:2023-10-28 21:11:56 26 4
gpt4 key购买 nike

导入标准的“日志”模块会用一堆虚拟条目污染 sys.modules:

Python 2.5.4 (r254:67916, Dec 23 2008, 15:10:54) [MSC v.1310 32 bit (Intel)] on win32
>>> import sys
>>> import logging
>>> sorted(x for x in sys.modules.keys() if 'log' in x)
['logging', 'logging.atexit', 'logging.cStringIO', 'logging.codecs',
'logging.os', 'logging.string', 'logging.sys', 'logging.thread',
'logging.threading', 'logging.time', 'logging.traceback', 'logging.types']

# and perhaps even more surprising:
>>> import traceback
>>> traceback is sys.modules['logging.traceback']
False
>>> sys.modules['logging.traceback'] is None
True

所以导入这个包会将额外的名称放入 sys.modules 中,除了它们不是模块,只是对 None 的引用。其他模块(例如 xml.dom 和编码)也有这个问题。为什么?

编辑:基于 bobince 的回答,有页面描述 the origin (参见“sys.modules 中的虚拟条目”一节)和future的功能。

最佳答案

sys.modules 中的

None 值是相对查找的缓存失败。

所以当你在 foo 包中并且你 import sys 时,Python 会首先查找 foo.sys 模块,如果是失败转到顶级 sys 模块。为了避免在进一步的相关导入时再次检查文件系统中的 foo/sys.py,它将 None 存储在 sys.modules 中以标记该模块不存在并且后续导入不应再次查看那里,而是直接转到加载的 sys

这是一个您无法有效依赖的 cPython 实现细节,但如果您正在执行令人讨厌的魔法导入/重新加载黑客攻击,则需要知道它。

它发生在所有包中,而不仅仅是 logging。例如,import xml.dom 并在模块列表中看到 xml.dom.xml,因为它试图从 内部导入 xml xml.dom.

随着 Python 朝着绝对导入的方向发展,这种丑陋的事情会越来越少。

关于python - 为什么 sys.modules 中有虚拟模块?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1958417/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com