使用 class 对象替换 sys.modules 中的当前模块时,导入的模块变为 None

imported modules becomes None when replacing current module in sys.modules using a class object

一个不受欢迎但 "supported" python hack(参见 Guido:https://mail.python.org/pipermail/python-ideas/2012-May/014969.html)启用 __getattr__ 在模块属性上的使用涉及以下内容:

import os, sys

class MyClass(object):

    def check_os(self):
        print os

sys.modules[__name__] = MyClass()

导入时,这个导入的模块变成了一个 class 实例:

>>> import myModule
>>> myModule
<myModule.MyClass object at 0xf76def2c>

但是,在 Python-2.7 中,原始模块中的所有其他导入模块都设置为 None。

>>> repro.check_os()
None

在Python-3.4中,一切正常:

>>> repro.check_os()
<module 'os' from '/python/3.4.1/lib/python3.4/os.py'>

这感觉像是与 Imported modules become None when running a function 有关,但是,有人知道为什么内部会发生这种情况吗?

似乎如果您存储原始模块(没有在 Python-2 中完全替换它)那么一切都会继续工作:

sys.modules[__name__+'_bak'] = sys.modules[__name__]      

你 运行 遇到的问题是,在 3.4 之前的 Python 中,当一个模块被销毁时(就像你的一样,因为你用 class 替换了它,并且没有进一步的引用it), 该模块的 __dict__ 中的项目被强制设置为 None.

如果您需要支持 3.4 之前的 Python,解决方法是在 class 中添加一个 import 语句来替换模块:

class MyClass(object):

    import os

    def check_os(self):
        print(os)

有关详细信息,请参阅 this answer about interpreter shutdown