代码之家  ›  专栏  ›  技术社区  ›  Peter Hansen

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

  •  17
  • Peter Hansen  · 技术社区  · 16 年前

    导入标准的“日志记录”模块会用一堆虚拟条目污染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和编码)也有这个问题。为什么?

    编辑: 根据波宾斯的回答,有几页描述 the origin (参见“系统模块中的虚拟条目”一节)和 future 特征。

    2 回复  |  直到 10 年前
        1
  •  23
  •   bobince    16 年前

    None 价值观 sys.modules 是相对查找的缓存失败。

    所以当你在包裹里的时候 foo 和你 import sys ,python首先查找 foo.sys 模块,如果失败,则转到顶层 sys 模块。为了避免检查文件系统 foo/sys.py 在进一步的相对进口上,它存储 没有 系统模块 要标记模块不存在,并且后续导入不应再次出现,而是直接转到加载的 系统 .

    这是一个你不能有效依赖的cpython实现细节,但是如果你做了令人讨厌的魔术导入/重新加载黑客,你需要知道它。

    它发生在所有的包裹上,不仅仅是 logging . 例如, import xml.dom 看到 xml.dom.xml 在模块列表中尝试导入 xml 从内部 xml.dom .

    随着python向绝对导入的方向发展,这种丑陋将不会发生。

        2
  •  0
  •   D.Shawley    16 年前

    我不知道为什么会这样,但是 encodings 显示相同的引用 None .

    Python 2.6.2 (r262:71600, May 24 2009, 00:12:54) 
    [GCC 4.0.1 (Apple Inc. build 5465)] on darwin
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import sys
    >>> for n in filter(lambda x: x.startswith('encodings'), sys.modules):
    ...  print n, type(sys.modules[n])
    ... 
    encodings <type 'module'>
    encodings.encodings <type 'NoneType'>
    encodings.codecs <type 'NoneType'>
    encodings.__builtin__ <type 'NoneType'>
    encodings.utf_8 <type 'module'>
    encodings.aliases <type 'module'>
    

    我真的不知道有些条目是怎么回事 没有 但我可以说,它不是唯一的 logging 模块。