"del sys.modules[module]" 实际上是做什么的?
What does "del sys.modules[module]" actually do?
众所周知,您可以del sys.modules[module]
删除导入的模块。所以我在想:这和重写sys.modules
有什么区别?一个有趣的事实是,重写 sys.modules
并不能真正删除一个模块。
# a_module.py
print("a module imported")
然后
import sys
def func1():
import a_module
# del sys.modules['a_module']
sys.modules = {
k: v for k, v in sys.modules.items() if 'a_module' not in k}
print('a_module' not in sys.modules) # True
def func2():
import a_module
func1() # a module imported
func2() # no output here
如果我使用del sys.modules['a_module']
,调用func2()
也会打印a module imported
,这意味着a_module
已成功删除。
我的问题是:del sys.modules[module]
除了改字典之外还有什么作用?
sys.modules
是 Python 可访问的参考 到 canonical 数据结构,用于跟踪模块是什么进口。从该字典中删除名称意味着以后任何导入该模块的尝试都将导致 Python 从头开始加载该模块。
换句话说,每当您使用 import
语句时,Python 做的第一件事就是检查 sys.modules
引用的字典是否已经有该模块的条目,然后继续下一步(在当前命名空间中绑定名称)而不首先加载模块。如果您从 sys.modules
中删除条目,则 Python 将找不到已加载的模块并再次加载。
请注意此处有关 Python-accessible 的谨慎措辞。实际的字典位于 Python 堆上,sys.modules
只是对它的一个引用。您通过分配给 sys.modules
, 用另一本词典替换了 那个引用。但是,解释器对它有 更多引用;它们只是无法从 Python 代码访问,而不是没有 ctypes
访问 C-API 的技巧。
However, replacing the dictionary will not necessarily work as expected and deleting essential items from the dictionary may cause Python to fail.
从 C-API,您必须使用 PyThreadState_Get()->interp->modules
来获取字典的内部引用。
众所周知,您可以del sys.modules[module]
删除导入的模块。所以我在想:这和重写sys.modules
有什么区别?一个有趣的事实是,重写 sys.modules
并不能真正删除一个模块。
# a_module.py
print("a module imported")
然后
import sys
def func1():
import a_module
# del sys.modules['a_module']
sys.modules = {
k: v for k, v in sys.modules.items() if 'a_module' not in k}
print('a_module' not in sys.modules) # True
def func2():
import a_module
func1() # a module imported
func2() # no output here
如果我使用del sys.modules['a_module']
,调用func2()
也会打印a module imported
,这意味着a_module
已成功删除。
我的问题是:del sys.modules[module]
除了改字典之外还有什么作用?
sys.modules
是 Python 可访问的参考 到 canonical 数据结构,用于跟踪模块是什么进口。从该字典中删除名称意味着以后任何导入该模块的尝试都将导致 Python 从头开始加载该模块。
换句话说,每当您使用 import
语句时,Python 做的第一件事就是检查 sys.modules
引用的字典是否已经有该模块的条目,然后继续下一步(在当前命名空间中绑定名称)而不首先加载模块。如果您从 sys.modules
中删除条目,则 Python 将找不到已加载的模块并再次加载。
请注意此处有关 Python-accessible 的谨慎措辞。实际的字典位于 Python 堆上,sys.modules
只是对它的一个引用。您通过分配给 sys.modules
, 用另一本词典替换了 那个引用。但是,解释器对它有 更多引用;它们只是无法从 Python 代码访问,而不是没有 ctypes
访问 C-API 的技巧。
However, replacing the dictionary will not necessarily work as expected and deleting essential items from the dictionary may cause Python to fail.
从 C-API,您必须使用 PyThreadState_Get()->interp->modules
来获取字典的内部引用。