"del sys.modules [module]"的作用是什么?真的吗? [英] What does "del sys.modules[module]" actually do?

查看:176
本文介绍了"del sys.modules [module]"的作用是什么?真的吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

众所周知,您可以执行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:

但是,替换字典不一定能按预期工作,并且从字典中删除必需项可能会导致Python失败.

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来获取字典的内部引用.

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]"的作用是什么?真的吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆