如果我导入模块,模块名称会同时显示在sys.modules
和globals()
中。如果我再次将其删除,则会从globals()
中删除,但仍会驻留在sys.modules
中。为什么会这样?
import mymodule
'mymodule' in globals() # True
'mymodule' in sys.modules # True
del mymodule
'mymodule' in globals() # False
'mymodule' in sys.modules # Still True, why?
我还发现了以下不同之处:
from mypackage import mymodule
'mypackage' in sys.modules # True
'mymodule' in sys.modules # False !
'mypackage.mymodule' in sys.modules # also True !
虽然答案是globals()
的补充:
'mypackage' in sys.modules # False
'mymodule' in sys.modules # True
'mypackage.mymodule' in sys.modules # False
答案 0 :(得分:4)
就像任何其他Python对象一样,模块继续存在,直到没有更多的引用。换句话说,sys.modules
的行为类似于常规字典,
import mymodule
lst = {mymodule.__name__: mymodule}
'mymodule' in globals() # True
'mymodule' in lst # True
del mymodule
'mymodule' in globals() # False
'mymodule' in lst # Still True
sys.modules
仅针对import语句进行咨询。您可以从sys.modules
删除模块,以便在下次导入时重新加载它。
答案 1 :(得分:4)
del
删除名称在适当范围内的绑定;它与模块本身无关。
sys.modules
会保留已加载的所有模块的列表,无论它们是否已绑定到程序中的任何名称。
答案 2 :(得分:3)
因为Python在sys.modules
中缓存模块,以防止(昂贵,缓慢)模块查找过程的运行超出必要的范围。
如果需要,可以从sys.modules
删除模块,但reload
也可以使用。
更详细地说,当import mymodule
发生各种事情时。在我的脑海中,假设mymodule
不是解释器可执行文件中内置的模块之一:
解释程序运行一些复杂的代码来查找包含mymodule
的文件(可能是mymodule.py
,mymodule.pyc
或mymodule.pyd
- 或者其他可能的内容我没有想过。这会查看当前目录,sys.path和其他地方。
这样定位的文件被解析,解析并编译(如果需要)到解释器字节码中。
执行编译的模块,给出一个模块对象。
模块对象被插入到sys.modules中。
模块对象绑定到import
语句中指定的局部变量。
(上面是一个非常粗略的近似,基于我对import
背后的机制的记忆。它在重要和微妙的方面可能是错误的。)
请注意,将模块对象绑定到本地名称实际上是实际导入过程的一小部分。通过执行del mymodule
来删除名称绑定不会影响导入的其余部分。