Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/solr/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 为什么sys.modules中有虚拟模块?_Python_Import - Fatal编程技术网

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

Python 为什么sys.modules中有虚拟模块?,python,import,Python,Import,导入标准“日志记录”模块会用一堆伪条目污染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', '

导入标准“日志记录”模块会用一堆伪条目污染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的回答,有一些页面描述了(请参阅“sys.modules中的虚拟条目”一节)和该功能。

sys.modules
中的无值是相对查找的缓存失败

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

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

它发生在所有包上,而不仅仅是
日志记录
。例如,
import xml.dom
,当它试图从
xml.dom
内部导入
xml
时,请参见模块列表中的
xml.dom.xml


随着Python朝着绝对导入的方向发展,这种丑恶的情况将更少发生。

谢谢!我在我的问题中添加了背景中的链接,并引用了,如果它“发生在所有包中”,为什么我从来没有在我自己的东西中看到过?我希望看到“mymodule.sys”、“mymodule.os”等等,周围有几十个这样的虚拟模块,但只看到一些,比如xml.dom、日志和编码(正如d.Shawley提到的),这发生在我的包上。但是只有包,而不是简单的模块。奇怪。我非常确定,过去为了各种调试目的,我经常检查sys.modules,但没有注意到sys.modules中引用的几十个stdlib模块是我的子包下的虚拟模块。然而,它们确实存在,例如,像“xxx.xxx.sys”这样的东西出现了16次。。。事实上,我以前在任何地方都没有发现这一点。显然,出于某种原因,我没有寻找明显的标题“说Neeeow…Wum…Ping的骑士”。啊,Python…我要发布一个完全相同的副本-我今天的第二个副本:P