sys.modules和globals()中的模块名称

时间:2011-08-19 12:47:21

标签: python

如果我导入模块,模块名称会同时显示在sys.modulesglobals()中。如果我再次将其删除,则会从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

3 个答案:

答案 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不是解释器可执行文件中内置的模块之一:

  1. 解释程序运行一些复杂的代码来查找包含mymodule的文件(可能是mymodule.pymymodule.pycmymodule.pyd - 或者其他可能的内容我没有想过。这会查看当前目录,sys.path和其他地方。

  2. 这样定位的文件被解析,解析并编译(如果需要)到解释器字节码中。

  3. 执行编译的模块,给出一个模块对象。

  4. 模块对象被插入到sys.modules中。

  5. 模块对象绑定到import语句中指定的局部变量。

  6. (上面是一个非常粗略的近似,基于我对import背后的机制的记忆。它在重要和微妙的方面可能是错误的。)

    请注意,将模块对象绑定到本地名称实际上是实际导入过程的一小部分。通过执行del mymodule来删除名称绑定不会影响导入的其余部分。