gpt4 book ai didi

Python 换出 sys.modules 并不像直觉那样工作

转载 作者:太空宇宙 更新时间:2023-11-04 02:56:41 25 4
gpt4 key购买 nike

我正在尝试设置字典 sys.modules,同时正在研究 another question 的答案。并遇到了一些有趣的事情。链接的问题涉及删除导入模块的所有影响。基于another post ,我想到了在导入后从 sys.modules 中删除所有新模块的想法。我最初的实现是执行以下操作(使用 numpy 作为要加载和卸载的模块进行测试):

# Load the module
import sys
mod_copy = sys.modules.copy()
print('numpy' in mod_copy, 'numpy' in sys.modules) # False False
import numpy
print('numpy' in mod_copy, 'numpy' in sys.modules) # False True
print(id(numpy)) # 45138472

打印输出显示 numpy 已成功导入,浅拷贝不包含它,正如预期的那样。

现在我的想法是通过将 mod_copy 换回 sys.modules 来卸载模块,然后删除对该模块的本地引用。理论上应该删除对它的所有引用(并且可能确实如此):

sys.modules = mod_copy
del numpy
print('numpy' in sys.modules) # False

这应该足以能够重新导入模块,但是当我这样做时

import numpy
print('numpy' in sys.modules) # False
print(id(numpy)) # 45138472

似乎 numpy 模块没有重新加载,因为它具有与以前相同的 id。它没有出现在 sys.modules 中,尽管 import 语句没有引发错误并且似乎成功完成(即 numpy 模块存在于本地命名空间中)。

另一方面,我在 my answer 中所做的实现链接的问题似乎工作正常。它直接修改字典而不是将其换出:

import sys
mod_copy = sys.modules.copy()
print('numpy' in mod_copy, 'numpy' in sys.modules) # False False
import numpy
print('numpy' in mod_copy, 'numpy' in sys.modules) # False True
print(id(numpy)) # 35963432

for m in list(sys.modules):
if m not in mod_copy:
del sys.modules[m]
del numpy
print('numpy' in sys.modules) # False

import numpy
print('numpy' in sys.modules) # True
print(id(numpy)) # (54941000 != 35963432)

我在 Anaconda 安装上使用 Python 3.5.2。我最感兴趣的是针对 Python 3 的解释,但我对 Python 2.7+ 也很好奇。

我唯一能想到的是,sys 维护了另一个对 sys.modules 的引用,并且无论我对公共(public)的。不过,我不确定这是否涵盖了所有内容,所以我想知道到底发生了什么。

最佳答案

即使在 Python 3.5 中,部分导入实现也是 still written in C ,并且该部分使用 PyThreadState_GET()->interp->modules 来检索模块缓存,而不是通过 sys.modules 属性。您的导入是通过这些代码路径之一在旧的 sys.modules 中找到 numpy

sys.modules 不是为了被替换而设计的。 docs提到替换它可能会出现意外行为:

This can be manipulated to force reloading of modules and other tricks. However, replacing the dictionary will not necessarily work as expected and deleting essential items from the dictionary may cause Python to fail.

关于Python 换出 sys.modules 并不像直觉那样工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42142660/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com