“del sys.modules[module]"是什么意思?其实呢? [英] What does "del sys.modules[module]" actually do?

查看:35
本文介绍了“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 import,这意味着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.modulesPython 可访问的参考规范用于跟踪导入哪些模块的数据结构.从该字典中删除名称意味着以后任何导入模块的尝试都将导致 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天全站免登陆