2012-07-08 58 views
2

我刚刚认识到,imp.reload()不删除旧的类和函数,如果它们从模块的源文件中删除。为什么python的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虽然它是从模块的源代码被删除。这是为什么?有没有办法识别模块的这些元素?

回答

4

根据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

相关问题