2

我刚刚认识到,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

1 回答 1

6

根据文档

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

try:
    cache
except NameError:
    cache = {}

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

import hashlib

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

hashlib = imp.reload(hashlib)

可怜hashlib

于 2012-07-08T03:04:38.340 回答