61

大きなモジュールがコードのサブモジュールによってロードされている場合、モジュールを再度インポートする代わりに、その名前空間からモジュールを参照する利点はありますか?

例: 私は、ReallyBigLib を広範囲に使用するモジュール MyLib を持っています。MyLib をインポートするコードがある場合、そのようにモジュールを掘り出す必要があります

import MyLib
ReallyBigLib = MyLib.SomeModule.ReallyBigLib

あるいは単に

import MyLib
import ReallyBigLib
4

6 に答える 6

83

Python モジュールはシングルトンと見なすことができます...何度インポートしても初期化されるのは 1 回だけなので、次のようにすることをお勧めします。

import MyLib
import ReallyBigLib

import ステートメントに関する関連ドキュメント:

https://docs.python.org/2/reference/simple_stmts.html#the-import-statement

モジュールの名前がわかったら (特に指定がない限り、「モジュール」という用語はパッケージとモジュールの両方を指します)、モジュールまたはパッケージの検索を開始できます。最初にチェックされるのは、以前にインポートされたすべてのモジュールのキャッシュである sys.modules です。モジュールがそこにある場合は、インポートのステップ (2) で使用されます。

インポートされたモジュールはsys.modulesにキャッシュされます:

これは、モジュール名を既にロードされているモジュールにマップする辞書です。これを操作して、モジュールのリロードやその他のトリックを強制することができます。このディクショナリからモジュールを削除することは、対応するモジュール オブジェクトで reload() を呼び出すことと同じではないことに注意してください。

于 2008-11-17T16:27:04.760 に答える
41

他の人が指摘しているように、Pythonはインポートされたすべてのモジュールの内部リストを保持しています。モジュールを初めてインポートするとき、モジュール(スクリプト)は最後まで独自の名前空間で実行され、内部リストが更新され、インポートステートメントの後に実行が続行されます。

このコードを試してください:

   # module/file a.py
   print "Hello from a.py!"
   import b

   # module/file b.py
   print "Hello from b.py!"
   import a

ループはありません。キャッシュルックアップのみがあります。

>>> import b
Hello from b.py!
Hello from a.py!
>>> import a
>>>

Pythonの美しさの1つは、名前空間でスクリプトを実行するためにすべてがどのように進化するかです。

于 2008-11-18T08:01:14.123 に答える
8

警告:Pythonは、モジュールが2回初期化されないことを保証しません。私はそのような問題に立ち向かった。ディスカッションを参照してください:http: //code.djangoproject.com/ticket/8193

于 2009-11-04T21:50:58.507 に答える
8

実質的な違いはありません。big モジュールが既にロードされている場合、2 番目の例の 2 番目のインポートは、現在の名前空間に 'ReallyBigLib' を追加する以外は何もしません。

于 2008-11-17T16:27:44.570 に答える
3

インポートされたモジュールの内部レジストリは、sys.modulesモジュール名をモジュール オブジェクトにマップするディクショナリです。そこを見て、現在インポートされているすべてのモジュールを確認できます。

また、モンキーを使用して (必要に応じて) いくつかの便利なトリックを引き出すこともできsys.modulesます。たとえば、独自のオブジェクトを、他のモジュールによってインポートできる疑似モジュールとして追加することができます。

于 2008-11-19T09:00:41.897 に答える
2

性能的には同じです。Python にはまだ JIT コンパイラがありません。

于 2008-11-17T16:24:20.023 に答える