2017-04-03 4 views
4

誰もが知っているように、del sys.modules[module]を実行すると、インポートされたモジュールを削除できます。だから私は考えていた:これは書き直しとはどう違うのですかsys.modules?興味深い事実は、書き直しsys.modulesは本当にモジュールを削除できないということです。「del sys.modules [module]」は実際に何をしていますか?

# a_module.py 
print("a module imported") 

その後

import sys 

def func1(): 
    import a_module 
    # del sys.modules['a_module'] 
    sys.modules = { 
     k: v for k, v in sys.modules.items() if 'a_module' not in k} 
    print('a_module' not in sys.modules) # True 

def func2(): 
    import a_module 

func1() # a module imported 
func2() # no output here 

私はdel sys.modules['a_module']を使用している場合は、func2()を呼び出すこともa_moduleが正常に削除されたことを意味する、a module importedを出力します。

私の質問は:del sys.modules[module]は実際に何をするのですか?

答えて

6

sys.modulesは、モジュールがインポートされるものを追跡するためカノニカルデータ構造へPythonのアクセス可能な参照あります。その辞書から名前を削除すると、将来モジュールをインポートしようとするとPythonはモジュールを最初からロードすることになります。言い換えれば

、あなたがimport文を使用したときに、Pythonのが最初に行うことは、辞書sys.modules参照がすでにそのモジュールのエントリを持っていることかどうかを確認し、次のステップは、(現在の名前空間で名前を結合)を進めずにいますまずモジュールをロードします。 sys.modulesからエントリを削除すると、Pythonは既にロードされているモジュールを見つけず、再度ロードします。

については、Pythonがアクセス可能なについて注意してください。実際の辞書はPythonヒープ上にあり、sys.modulesはそれを参照しているに過ぎません。 sys.modulesに割り当てて別の辞書で参照するを置き換えました。しかし、通訳者にはの参照があります。;彼らはちょうどPythonコードからアクセスすることはできません。​​がC-APIにアクセスするのは面倒です。これはexplicitly documentedであることを

注:

しかし、予想通りの辞書を交換することは、必ずしも機能しませんし、辞書から必須項目を削除すると、Pythonが失敗する可能性があります。

C-APIから、辞書への内部参照を取得するには、PyThreadState_Get()->interp->modulesを使用する必要があります。

+0

ありがとうございます。これはどこかに書かれていますか?私は、 "より多くの参考文献"があることを知らなかった。 – laike9m

+0

@ laike9m:これは実装の詳細です。私はソースコードですばらしいダイブをしました。他のPythonの実装は、インタプリタの状態を異なる方法で処理する可能性があります。 –

+1

@ laike9m:たとえば、[PyInterpreterState'のC APIドキュメント](https://docs.python.org/3/c-api/init.html#c.PyInterpreterState)には言及がありません'sys.modules'のドキュメントは、' sys.modules'リファレンスの置き換えに対して明示的に警告します。 –

関連する問題