web-dev-qa-db-ja.com

モジュールが2回インポートされないようにするにはどうすればよいですか?

pythonモジュールを作成する場合、クライアントコードによって2回インポートされるのを防ぐ方法はありますか?c/c ++ヘッダーファイルと同じように:

#ifndef XXX
#define XXX
...
#endif

どうもありがとう!

32
KL.

Pythonモジュールは複数回インポートされません。 importを2回実行するだけでは、モジュールはリロードされません。再読み込みする場合は、reloadステートメントを使用する必要があります。これがデモです

foo.pyは1行のモジュールです

print "I am being imported"

そして、これが複数のインポート試行の画面トランスクリプトです。

   >>> import foo
   Hello, I am being imported
   >>> import foo # Will not print the statement
   >>> reload(foo) # Will print it again
   Hello, I am being imported
39
Noufal Ibrahim

インポートはキャッシュされ、1回だけ実行されます。追加のインポートには、sys.modulesでのルックアップ時間のみがかかります。

他の回答で指定されているように、Pythonは通常、モジュールの2番目のインポートステートメントが検出されたときにモジュールをリロードしません。代わりに、コードを実行せずに、キャッシュされたバージョンをsys.modulesから返します。

ただし、注目に値するいくつかの落とし穴があります。

  • メインモジュールを通常のモジュールとしてインポートすると、同じモジュールの2つのインスタンスが異なる名前で効果的に作成されます。

    これは、プログラムの起動時に メインモジュールが__main__という名前で設定されている であるために発生します。したがって、通常のモジュールとしてインポートする場合、Pythonsys.modulesでそれを検出せずに再度インポートしますが、2回目は適切な名前でインポートします。

    次の内容のファイル/ tmp/a.pyについて考えてみます。

    # /tmp/a.py
    import sys
    
    print "%s executing as %s, recognized as %s in sys.modules" % (__file__, __name__, sys.modules[__name__])
    import b
    

    別のファイル/ tmp/b.pyには、a.pyimport a)の単一のインポートステートメントがあります。
    / tmp/a.pyを実行すると、次の出力が生成されます。

    root@machine:/tmp$ python a.py
    a.py executing as __main__, recognized as <module '__main__' from 'a.py'> in sys.modules
    /tmp/a.pyc executing as a, recognized as <module 'a' from '/tmp/a.pyc'> in sys.modules
    

    したがって、アドバイスに従って、メインモジュールを最小限に抑え、その機能のほとんどを外部モジュールにエクスポートすることをお勧めします ここ

  • この回答 さらに2つの可能なシナリオを指定します。

    1. 同じモジュールにつながるsys.pathの異なるエントリを利用するわずかに異なるインポートステートメント。
    2. 前のモジュールが途中で失敗した後、モジュールの別のインポートを試みました。
14
Yoel