2011-08-19 9 views
9

モジュールをインポートすると、モジュール名はsys.modulesglobals()の両方に表示されます。再度削除すると、globals()から削除されますが、依然としてsys.modulesにあります。それはなぜそうですか?答えはglobals()のために相補的である一方でsys.modulesとglobalsのモジュール名

from mypackage import mymodule 
'mypackage' in sys.modules   # True 
'mymodule' in sys.modules   # False ! 
'mypackage.mymodule' in sys.modules # also True ! 

'mypackage' in sys.modules   # False 
'mymodule' in sys.modules   # True 
'mypackage.mymodule' in sys.modules # False 
+0

sys.modules、 'del sys.modules ['mymodule']'からモジュールを削除することができますが、これは時に便利です。 – SingleNegationElimination

答えて

4

他のPythonオブジェクトと同じように、モジュールは参照がなくなるまで存在し続けます。言い換えれば、sys.modulesは、通常の辞書のように振る舞い、そして

import mymodule 
lst = {mymodule.__name__: mymodule} 
'mymodule' in globals() # True 
'mymodule' in lst   # True 
del mymodule 
'mymodule' in globals() # False 
'mymodule' in lst   # Still True 

sys.modulesだけimport文で参照されます。 sys.modulesからモジュールを削除して、次回のインポート時にPythonがリロードするようにすることができます。

3

Pythonは(高価な遅い)を防止するためにsys.modules内のモジュールをキャッシュするので

import mymodule 
'mymodule' in globals() # True 
'mymodule' in sys.modules # True 
del mymodule 
'mymodule' in globals() # False 
'mymodule' in sys.modules # Still True, why? 

私はまた、次の相違点を発見しましたモジュール発見プロセスは必要以上に実行されます。

必要ならばsys.modulesからモジュールを削除しても問題ありませんが、reloadも機能する場合があります。


さらに詳しくは、import mymoduleの場合、さまざまなことが起こります。私の頭の上、及びmymoduleはインタプリタの実行可能ファイルに組み込まれたモジュールの一つではないと仮定オフ:

  1. インタプリタmymoduleを含むファイルを見つけるためにいくつかの複雑なコードを実行します(これはmymodule.pymymodule.pycかもしれ、またはmymodule.pyd - これは私が考えていないもので、現在のディレクトリ、sys.path、その他の場所を調べます。必要に応じて)インタプリタのバイトコードに変換する。

  2. コンパイルされたモジュールが実行され、モジュールオブジェクトが生成されます。

  3. モジュールオブジェクトはsys.modulesに挿入されます。

  4. モジュールオブジェクトは、importステートメントで指定されたローカル変数にバインドされています。

(上記の私はimportの背後にある仕組みについて覚えた内容に基づいて非常に粗い近似である。それは重要かつ微妙な方法で、おそらく間違っているのです。)

注、その後にモジュールオブジェクトを結合することをローカル名は実際には実際のインポートプロセスのかなりの部分です。 del mymoduleを実行して名前バインディングを削除しても、残りのインポートには影響しません。

+1

'del mymodule'を実行して名前のバインディングを削除した場合、名前空間から削除して' import mymodule'を実行することができます。これらの2つのステップは、 'reload(mymodule)'を実行するのと同じです。 – HongboZhu

+1

@Hongbo:間違っています: 'import'は' sys.modules'の中で最初にモジュールをインポートしたかどうかを調べます。それが持っている場合、モジュールを最後にインポートしたときに作成したモジュールオブジェクトを提供します。 'del mymodule'は' sys.modules'からモジュールオブジェクトを削除しないので、 'sys.modules'のオブジェクトに名前を再バインドするだけです。 – katrielalex

+1

@香港:モジュールを再インポートする場合は、 'reload(module)'を実行します。同様に、 'sys.modules'からそれを削除し、' import'します。 – katrielalex

4

delは、適切なスコープ内の名前のバインディングを削除します。モジュールそのものとは何の関係もありません。

sys.modulesは、プログラム内の任意の名前にバインドされているかどうかに関係なく、ロードされたすべてのモジュールのリストを保持します。

関連する問題