问题描述
众所周知,您可以执行del sys.modules[module]
删除导入的模块.所以我在想:这与重写sys.modules
有何不同?一个有趣的事实是,重写sys.modules
不能真正删除模块.
As everyone knows, you can do del sys.modules[module]
to delete an imported module. So I was thinking: how is this different from rewriting sys.modules
? An interesting fact is, rewriting sys.modules
can't truely delete a module.
# 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
已成功删除.
If I use del sys.modules['a_module']
, calling func2()
also prints a module imported
, which implies that a_module
is successfully deleted.
我的问题是:除了更改字典之外,del sys.modules[module]
实际上是做什么的?
My question is: What does del sys.modules[module]
actually do, besides changing the dictionary?
推荐答案
sys.modules
是 canonical 数据结构的 Python可访问引用,用于跟踪哪些模块是进口的.从该词典中删除名称意味着将来尝试导入该模块将导致Python从头开始加载该模块.
sys.modules
is the Python-accessible reference to the canonical data structure for tracking what modules are imported. Removing a name from that dictionary means that any future attempts to import the module will result in Python loading the module from scratch.
换句话说,每当您使用import
语句时,Python要做的第一件事就是检查sys.modules
引用的字典是否已经有该模块的条目,然后继续下一步(在当前目录中绑定名称).命名空间),而无需先加载模块.如果您从sys.modules
中删除条目,则Python将找不到已加载的模块并再次加载.
In other words, whenever you use an import
statement, the first thing Python does is check if the dictionary that sys.modules
references already has an entry for that module and proceed with the next step (binding names in the current namespace) without loading the module first. If you delete entries from sys.modules
, then Python won't find the already-loaded module and loads again.
请注意此处有关 Python可访问的谨慎措辞.实际的字典位于Python堆上,sys.modules
只是对其的一个引用.通过分配给sys.modules
,您可以用另一本词典替换.但是,解释器有更多引用;它们只是无法从Python代码访问,或者总是有ctypes
技巧来访问C-API.
Note the careful wording about Python-accessible here. The actual dictionary lives on the Python heap and sys.modules
is just one reference to it. You replaced that reference with another dictionary by assigning to sys.modules
. However, the interpreter has more references to it; they just are not accessible from Python code, not without ctypes
trickery to access the C-API anyway.
请注意,这是 明确记录的 :
Note that this is explicitly documented:
从C-API中,您必须使用PyThreadState_Get()->interp->modules
来获取字典的内部引用.
From the C-API, you'd have to use PyThreadState_Get()->interp->modules
to get the internal reference to the dictionary.
这篇关于"del sys.modules [module]"的作用是什么?真的吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!