为什么 sys.modules 中有虚拟模块? [英] Why are there dummy modules in sys.modules?

查看:21
本文介绍了为什么 sys.modules 中有虚拟模块?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Importing the standard "logging" module pollutes sys.modules with a bunch of dummy entries:

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 和 encodings)也有这个问题.为什么?

So importing this package puts extra names into sys.modules, except that they are not modules, just references to None. Other modules (e.g. xml.dom and encodings) have this issue as well. Why?

基于 bobince 的回答,有一些页面描述了 来源(参见sys.modules 中的虚拟条目"部分)和 该功能的未来.

Building on bobince's answer, there are pages describing the origin (see section "Dummy Entries in sys.modules") and future of the feature.

推荐答案

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

None values in sys.modules are cached failures of relative lookups.

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

So when you're in package foo and you import sys, Python looks first for a foo.sys module, and if that fails goes to the top-level sys module. To avoid having to check the filesystem for foo/sys.py again on further relative imports, it stores None in the sys.modules to flag that the module didn't exist and a subsequent import shouldn't look there again, but go straight to the loaded sys.

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

This is a cPython implementation detail you can't usefully rely on, but you will need to know it if you're doing nasty magic import/reload hacking.

它发生在所有包中,而不仅仅是 logging.例如,当它尝试从 内部导入 xml 时,import xml.dom 并在模块列表中查看 xml.dom.xmlxml.dom.

It happens to all packages, not just logging. For example, import xml.dom and see xml.dom.xml in the module list as it tries to import xml from inside xml.dom.

随着 Python 朝着绝对导入的方向发展,这种丑陋的情况会减少.

As Python moves towards absolute import this ugliness will happen less.

这篇关于为什么 sys.modules 中有虚拟模块?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆