我刚认识到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
,尽管它已从模块源代码中删除。为什么会这样?有没有办法识别模块的这些元素?
答案 0 :(得分:5)
如果新版本的模块未定义旧版本定义的名称,则旧定义仍然存在。如果该模块维护对象的全局表或缓存,则可以使用此功能 - 使用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
。