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 = {}

だから。それらの古いオブジェクトが必要ない場合は、リロードする前にモジュールのディクショナリを空にすることができます。たとえば、ここでは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 に答える