当前位置: 首页 > 面试题库 >

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

韶和璧
2023-03-14
问题内容

一个不受欢迎但受支持的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()

在导入时,此导入的模块将成为类实例:

>>> 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'>

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

看来,如果您存储原始模块(在Python-2中没有完全替换它),那么一切将继续进行:

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

问题答案:

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

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

class MyClass(object):

    import os

    def check_os(self):
        print(os)

有关更多信息,请参见有关解释器关闭的答案。



 类似资料:
  • 我想将导入的模块替换为存根,以便只对主模块进行单元测试。我试过用西农。但是它似乎并没有达到我期望的效果,因为我在运行测试时不断遇到错误。 这是我的主要模块。 这是我的测试。 我是不是做错了什么?任何帮助将不胜感激。

  • 问题内容: 我正在编写一个小脚本,该脚本从目录获取文件名,并将其传递给另一个模块,然后该模块导入文件。 因此流程类似于1)获取模块名称(将其存储在变量中)2)将此变量名称传递给模块3)导入名称存储在变量名称中的模块 我的代码就像 问题在于,当它到达import语句时,它将modulename读取为真实的模块名称,而不是存储在此变量中的值。我不确定这在python中如何工作,解决这个问题的任何帮助都

  • 根据这个答案,您可以使用来使用类似这样的相对导入: 为什么相对导入不适用于sklearn。特征提取。文本 我验证了是一个具有以下功能的模块: 编辑 “不工作”,我的意思是它不导入模块。 我正在使用Python 3.4 绝对方式工作: 相对方式不:

  • 我有以下设置。我正在尝试动态加载 a.py 模块(在这种情况下从 c.py 加载,并将其调用为BeLoaded)。然后我想导入另一个模块文件B,它有一个类,该类将继承该类到BeLoaded.otherClass。我知道如果我在 b.py 中导入 c.py 可以解决问题,但由于我是动态加载 c.py,我不确定如何做到这一点。如果我可以在导入变量之前以某种方式将变量传递给 b.py,它将起作用,但我不

  • 由于使用了容器模式来组织各模块的实例,意味着你可以比较容易的替换掉已经有的服务,以公众号服务为例: <...> $app = Factory::officialAccount($config); $app->rebind('request', new MyCustomRequest(...)); 这里的 request 为 SDK 内部服务名称。

  • 问题 你想给某个已存在模块中的函数添加装饰器。 不过,前提是这个模块已经被导入并且被使用过。 解决方案 这里问题的本质就是你想在模块被加载时执行某个动作。 可能是你想在一个模块被加载时触发某个回调函数来通知你。 这个问题可以使用10.11小节中同样的导入钩子机制来实现。下面是一个可能的方案: # postimport.py import importlib import sys from coll