要するに、Python では、同じモジュールの複数のインスタンスを作成するのは非常に簡単で、各インスタンスには独自のグローバル変数のセットがあります。
このような複数のインスタンス化を検出して例外を発生させるには、モジュールにチェックを追加する必要があります。
私の問題はこれと同じです: モジュールが複数回インポートされました
これは、問題を再現するための最小のディレクトリ構造です。
/test/a/__init__.py
/test/a/aa.py:
print "aa: __name__: ", __name__
/test/b/b.py:
from a import aa
import aa
それで
export PYTHONPATH=/test:/test/a
python /test/b/b.py
プリント:
aa: __name__: a.aa
aa: __name__: aa
そのため、モジュール aa.py が異なる名前で 2 回インポートされました。
言うまでもなく、モジュール aa.py は 2 セットのグローバル変数を取得するため、このモジュール内のすべてのロジックが台無しになります。
もちろん、上記の些細な例では、目でエラーを検出するのは簡単ですが、複数のサブディレクトリを持つ複雑なプロジェクトでは、これらのエラーが定期的に発生し続けます。
したがって、本当にグローバルな変数やプロセス全体のストアなどが必要です。何か案が?
編集: Bibhas は、同じグローバル変数の複数のインスタンスの例を求めました。ここにあります:
/test/a/__init__.py
/test/a/aa.py:
print "aa: __name__: ", __name__
import thread
import time
test_var = __name__
def test():
for i in range(0,5):
print "aa thread: test_var: ", test_var
time.sleep(1)
thread.start_new_thread( test, () )
/test/b/b.py:
print "b: __name__: ", __name__
from a import aa
import aa
import time
time.sleep(10)
現在実行中
export PYTHONPATH=/test:/test/a
python /test/b/b.py
プリント:
aa: __name__: a.aa
aa: __name__: aa
aa thread: test_var: aa
aa thread: test_var: a.aa
aa thread: test_var: aa
aa thread: test_var: a.aa
...
したがって、変数 test_var の 2 つのインスタンスがあることは明らかです。このモジュールにシングルトンを実装しようとすると、このシングルトンのインスタンスが 2 つになります。
Edit2:したがって、Guy Lが提案するソリューションは次のようなものです:
/test/a/aa.py:
import os
if "aa.py" in os.environ:
raise Exception("Duplicate instantiation of aa.py")
os.environ["aa.py"] = __name__
問題なく動作するようです (複数のスレッドで import を呼び出さない限り)。誰かがより良いものを持っていますか?