为什么python的imp.reload()不会删除旧的类和函数?

时间:2012-07-08 02:57:26

标签: python object python-3.x module reload

我刚认识到imp.reload()如果从模块的源文件中删除它们,则不会删除旧的类和函数。

一个例子:

:~$ python3
Python 3.2.3 (default, May  3 2012, 15:54:42) 
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> print(open("test.py").read())
# empty file
>>> import test
>>> dir(test)
['__builtins__', '__cached__', '__doc__', '__file__', '__name__',
'__package__']
>>> print(open("test.py").read())                             
# new class A and B added
class A:                                                      
        pass                                                  

class B:                                                      
        pass

>>> import imp
>>> dir(imp.reload(test))
['A', 'B', '__builtins__', '__cached__', '__doc__', '__file__', '__name__',
'__package__']
>>> print(open("test.py").read())
# class A deleted
class B:
        pass

>>> dir(imp.reload(test))
['A', 'B', '__builtins__', '__cached__', '__doc__', '__file__', '__name__',
'__package__']
>>> import sys
>>> dir(sys.modules['test'])
['A', 'B', '__builtins__', '__cached__', '__doc__', '__file__', '__name__',
'__package__']
>>> sys.modules['test'].A
<class 'test.A'>

在最后几行中,您可以看到有一个类对象A,尽管它已从模块源代码中删除。为什么会这样?有没有办法识别模块的这些元素?

1 个答案:

答案 0 :(得分:5)

根据the documentation

  

如果新版本的模块未定义旧版本定义的名称,则旧定义仍然存在。如果该模块维护对象的全局表或缓存,则可以使用此功能 - 使用try语句可以测试表的存在并在需要时跳过其初始化:

try:
    cache
except NameError:
    cache = {}

所以这就是原因。如果您不想要那些旧对象,则可以在重新加载之前清空模块的字典。例如,在这里我将导入hashlib,清空其字典,然后重新加载它。

import hashlib

for attr in dir(hashlib):
    if attr not in ('__name__', '__file__'):
        delattr(hashlib, attr)

hashlib = imp.reload(hashlib)

hashlib