我正在尝试调试导致sys.modules['numpy']
被覆盖的问题。我在numpy.__init__
中添加了一些打印语句,当我尝试导入numpy时,得到以下输出:
numpy.__init__ running
id(sys.modules) = 89034704
id(sys.modules['numpy']) = 161528304
numpy.__init__ running
id(sys.modules) = 89034704
id(sys.modules['numpy']) = 177135864
Numpy具有许多循环导入,它们应按照this answer中的说明工作。但是在我的情况下,不是从
sys.modules
获取部分初始化的numpy模块,而是再次导入numpy,然后再次执行numpy.__init__
,从而导致崩溃。如何检测
sys.modules
以获得谁在何时覆盖sys.modules['numpy']
的可见性?通常,我会写一个dict子类,但我认为更改sys.modules
指向自己的对象并不安全。我尝试覆盖sys.modules.__setattr__
,但这是一个只读属性。上下文:我正在尝试在Julia库PyCall中调试this issue。 PyCall将Python解释器嵌入正在运行的Julia进程中,然后将导入从cpython委托给
PyImport_ImportModule
。上面的问题只在对PyImport_ImportModule
的一次调用中发生,所以我希望这个问题应该能够在python / cpython知识的情况下得到解答,但不知道Julia / PyCall的知识。 最佳答案
您可以将sys.modules
从普通的dict
更改为prints
分配的内容,例如:
import sys
import traceback
class noisydict(dict):
def __setitem__(self, key, value):
print('ASSIGNED: key={!r} value={!r} at:'.format(key, value))
traceback.print_stack()
return dict.__setitem__(self, key, value)
sys.modules = noisydict(sys.modules)
如果覆盖发生在C代码中(这可能直接访问底层的
dict.__setitem__
而不是像Python代码那样仅执行sys.modules[name] = newmodule
),则此方法可能行不通,但值得一试!