2016-10-08 11 views
0

最終的に私は自分の質問をしています。ソースから動的にインポートされたファイルのアンロード/デコンストラクションを強制的に実行する

私は、特定の名前を持つPythonモジュールのディレクトリを再帰的に調べる自動化スクリプト/モジュールを作成しています。その名前のモジュールを見つけたら、動的にロードし、必要なものを取り出してからアンロードします。モジュールを削除するだけでそのモジュールへの参照がすべて削除されるわけではありませんが、別の場所が残っていて、どこにあるのかわかりません。私はソースコードを覗いてみましたが、それをあまりうまく理解できませんでした。ここに私が見ているもののサンプルがあり、大きく簡略化されています。

私はPython 3.5.2(Anaconda v4.2.0)を使用しています。私はimportlibを使用しています。それは私が守りたいものです。私はまた、これをvanilla python-3でやりたいと思っています。

私はPythonのドキュメントhere(これはPython 3.6のドキュメントです)からソースからインポートを取得しました。

私の主なドライバ...

# main.py 
import importlib.util 
import sys 

def foo(): 
    spec = importlib.util.spec_from_file_location('a', 'a.py') 
    module = importlib.util.module_from_spec(spec) 
    spec.loader.exec_module(module) 
    print(sys.getrefcount(module)) 
    del module 
    del spec 

if __name__ == '__main__': 
    foo() 
    print('THE END') 

そして、私のサンプルモジュール...

# a.py 
print('hello from a') 

class A(): 
    def __del__(self): 
     print('SO LONG A!') 

inst = A() 

は出力:

python main.py 
HELLO FROM A! 
2 
THE END 
SO LONG A! 

私が見に期待 "SO LONG Aを!" "THE END"の前に印刷されます。だから、私のモジュールへのこの他の隠れた参照はどこにありますか?私はデルのものは、私はそれが関数で包まれているという事実と無償であることを理解します。私は削除とスコープを明確にしたかっただけです。どうすればa.pyを完全にアンロードできますか?私はa.pyのような大量のモジュールを動的にロードすることを計画しています。私が紛失しているものはありますか?

答えて

0

ここで循環参照があります。モジュールオブジェクトは、モジュールを再度参照するオブジェクトを再度参照します。

これは、モジュールがただちにクリアされないことを意味します(参照カウントが0になることはありません)。ガベージコレクタによって円が壊れるのを待つ必要があります。

あなたはgc.collect()を呼び出すことで、これを強制することができます。代わりにそれと

import gc 

# ... 

if __name__ == '__main__': 
    foo() 
    gc.collect() 
    print('THE END') 

を、出力は次のようになります。確かにそれをやった

$ python main.py 
hello from a 
2 
SO LONG A! 
THE END 
+0

ああ、!あなたの答えを受け入れました。ありがとうございました! – Lnk2past

関連する問題