Python モジュールが 2 回インポートされる原因は何でしょうか? 質問する

Python モジュールが 2 回インポートされる原因は何でしょうか? 質問する

私の理解する限り、Python モジュールは 2 回インポートされることはありません。つまり、モジュール内のコードは最初にインポートされたときにのみ実行されます。後続のインポート ステートメントは、モジュールをインポートのスコープに追加するだけです。

ただし、「TiledConvC3D.py」というモジュールがあり、これは複数回インポートされているようです。このモジュールのコードの先頭にあるスタックを印刷するには、pdb を使用します。

以下は、モジュールが最初に実行されたときのスタック トレースの終わりです。

File "<anonymized>/python_modules/Theano/theano/gof/cmodule.py", line 328, in refresh
  key = cPickle.load(open(key_pkl, 'rb'))
File "<anonymized>/ops/TiledConvG3D.py", line 565, in <module>
  import TiledConvC3D
File "<anonymized>/ops/TiledConvC3D.py", line 18, in <module>
  pdb.traceback.print_stack()

これはさらに数回実行されます。ただし、2 回目の呼び出しの完全なスタック トレースには の呼び出しが表示されないreloadため、これらの実行は発生しないはずです。

File "sup_train_conj_grad.py", line 103, in <module>
  dataset = Config.get_dataset(dataset_node)
File "<anonymized>/Config.py", line 279, in get_dataset
  from datasets import NewWiskott
File "<anonymized>/datasets/NewWiskott.py", line 16, in <module>
  normalizer_train = video.ContrastNormalizer3D(sigma, global_per_frame = False, input_is_5d = True)
File "<anonymized>/util/video.py", line 204, in __init__
  self.f = theano.function([input],output)
File "<anonymized>/python_modules/Theano/theano/compile/function.py", line 105, in function
  allow_input_downcast=allow_input_downcast)
File "<anonymized>/python_modules/Theano/theano/compile/pfunc.py", line 270, in pfunc
  accept_inplace=accept_inplace, name=name)
File "<anonymized>/python_modules/Theano/theano/compile/function_module.py", line 1105, in orig_function
  fn = Maker(inputs, outputs, mode, accept_inplace = accept_inplace).create(defaults)
File "/u/goodfeli/python_modules/Theano/theano/compile/function_module.py", line 982, in create
  _fn, _i, _o = self.linker.make_thunk(input_storage = input_storage_lists)
File "<anonymized>/python_modules/Theano/theano/gof/link.py", line 321, in make_thunk
  output_storage = output_storage)[:3]
File "<anonymized>/python_modules/Theano/theano/gof/cc.py", line 1178, in make_all
  output_storage = node_output_storage)
File "<anonymized>/python_modules/Theano/theano/gof/cc.py", line 774, in make_thunk
  cthunk, in_storage, out_storage, error_storage = self.__compile__(input_storage, output_storage)
File "<anonymized>/python_modules/Theano/theano/gof/cc.py", line 723, in __compile__
  output_storage)
File "<anonymized>/python_modules/Theano/theano/gof/cc.py", line 1037, in cthunk_factory
  module = get_module_cache().module_from_key(key=key, fn=self.compile_cmodule)
File "<anonymized>/python_modules/Theano/theano/gof/cc.py", line 59, in get_module_cache
  return cmodule.get_module_cache(config.compiledir)
File "<anonymized>/python_modules/Theano/theano/gof/cmodule.py", line 576, in get_module_cache
  _module_cache = ModuleCache(dirname, force_fresh=force_fresh)
File "<anonymized>/python_modules/Theano/theano/gof/cmodule.py", line 268, in __init__
  self.refresh()
File "<anonymized>/python_modules/Theano/theano/gof/cmodule.py", line 326, in refresh
  key = cPickle.load(open(key_pkl, 'rb'))
File "<anonymized>/ops/TiledConvV3D.py", line 504, in <module>
  import TiledConvG3D
File "<anonymized>/ops/TiledConvG3D.py", line 565, in <module>
  import TiledConvC3D
File "<anonymized>/ops/TiledConvC3D.py", line 22, in <module>
  pdb.traceback.print_stack()

さらに、 の ID も確認します__builtin__.__import__。メイン スクリプトの最初に、他のインポートを行う前にインポート__builtin__して印刷します。また、複数回インポートされているモジュール内からも印刷しますが、 ID の値は変わりません。id(__builtin__.__import__)id(__builtin__.import__)

__builtin__.__import__リロードを呼び出してオーバーライドする以外に、モジュールが複数回ロードされる原因となるメカニズムはありますか?

ベストアンサー1

Python モジュールがパス内に 2 回見つかった場合、そのモジュールは 2 回インポートされる可能性があります。たとえば、プロジェクトが次のように配置されているとします。

  • ソース/
    • パッケージ1/
      • スパム.py
      • 卵.py

PYTHONPATH (sys.path) に src と src/package1 が含まれているとします。

PYTHONPATH=/path/to/src:/path/to/src/package1

その場合は、次のように同じモジュールを 2 回インポートできます。

from package1 import spam
import spam

そして、Python はそれらを異なるモジュールであると認識します。それが起こっているのでしょうか?

また、以下の議論(この質問を検索しているユーザー向け)によると、モジュールが2回インポートされる別の方法は、最初のインポートの途中で例外が発生した場合です。たとえば、spamが卵をインポートしたが、卵をインポートすると例外が発生する場合などです。モジュール内部再度インポートすることができます。

おすすめ記事