2012-07-08 69 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

相關問題