lai*_*e9m 5 python module sys python-internals
众所周知,您可以del sys.modules[module]删除导入的模块.所以我在想:这与重写有sys.modules什么不同?一个有趣的事实是,重写sys.modules不能真正删除模块.
# a_module.py
print("a module imported")
Run Code Online (Sandbox Code Playgroud)
然后
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
Run Code Online (Sandbox Code Playgroud)
如果我使用del sys.modules['a_module'],调用func2()也打印a module imported,这意味着a_module成功删除.
我的问题是:del sys.modules[module]除了更改字典之外,实际上做了什么?
Mar*_*ers 11
sys.modules是用于跟踪导入模块的规范数据结构的Python可访问引用.从该字典中删除名称意味着将来导入模块的任何尝试都将导致Python从头开始加载模块.
换句话说,每当你使用一个import语句时,Python所做的第一件事就是检查sys.modules引用的字典是否已经有该模块的条目,并继续下一步(在当前命名空间中绑定名称)而不先加载模块.如果删除条目sys.modules,则Python将找不到已加载的模块并再次加载.
请注意这里关于Python的谨慎措辞.实际的字典存在于Python堆上,sys.modules只是对它的一个引用.您通过分配将该引用替换为另一个字典sys.modules.但是,口译员对此有更多的参考 ; 他们只是无法从Python代码ctypes访问,无论如何都不能无需访问C-API.
请注意,这是明确记录的:
但是,替换字典不一定按预期工作,从字典中删除基本项可能会导致Python失败.
从C-API,您必须使用PyThreadState_Get()->interp->modules获取字典的内部引用.
| 归档时间: |
|
| 查看次数: |
2301 次 |
| 最近记录: |