使用类对象替换 sys.modules 中的当前模块时,导入的模块变为 None [英] imported modules becomes None when replacing current module in sys.modules using a class object

查看:154
本文介绍了使用类对象替换 sys.modules 中的当前模块时,导入的模块变为 None的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

import os, sys类 MyClass(对象):def check_os(self):打印操作系统sys.modules[__name__] = MyClass()

在导入时,这个导入的模块成为一个类实例:

<预><代码>>>>导入我的模块>>>我的模块<位于 0xf76def2c 的 myModule.MyClass 对象>

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

<预><代码>>>>repro.check_os()没有任何

在 Python-3.4 中,一切正常:

<预><代码>>>>repro.check_os()<来自'/python/3.4.1/lib/python3.4/os.py'的模块'os'>

这感觉与导入的模块在运行时变成None有关一个函数,但是,有人知道为什么会在内部发生这种情况吗?

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

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

解决方案

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

解决方法,如果您需要支持 3.4 之前的 Python,则在将替换模块的类中有一个 import 语句:

class MyClass(object):导入操作系统def check_os(self):打印(操作系统)

有关详细信息,请参阅有关解释器关闭的答案.

an unpopular but "supported" python hack (see Guido: https://mail.python.org/pipermail/python-ideas/2012-May/014969.html) that enables __getattr__ usage on module attributes involves the following:

import os, sys

class MyClass(object):

    def check_os(self):
        print os

sys.modules[__name__] = MyClass()

On import, this the imported module becomes a class instance:

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

However, in Python-2.7, all other imported modules within the original module is set to None.

>>> repro.check_os()
None

In Python-3.4, everything works:

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

This feels like something to do with Imported modules become None when running a function, but, anyone knows why this happens internally?

It seems that if you store the original module (without fully replacing it in Python-2) then everything continues to work:

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

解决方案

The problem you are running in to is that in Pythons prior to 3.4 when a module is destroyed (as yours is because you replace it with a class and there are no further references to it), the items in that module's __dict__ are forcibly set to None.

The workaround, if you need to support Pythons prior to 3.4, is have an import statement in the class that will replace the module:

class MyClass(object):

    import os

    def check_os(self):
        print(os)

For more info, see this answer about interpreter shutdown.

这篇关于使用类对象替换 sys.modules 中的当前模块时,导入的模块变为 None的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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