2011-01-25 15 views
11

私が理解する限り、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() 

それは、数回実行することに進みます。しかし、それが呼び出された二回目のための完全なスタックトレースが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() 

また、私はまた__builtin__.__import__のIDを確認してください。私の主なスクリプトの冒頭で、他のインポートを行う前に、__builtin__id(__builtin__.__import__)をインポートします。私もid(__builtin__.import__)を複数回インポートされている私のモジュールの中から印刷し、idの値は変更されません。

リロードを呼び出して、をオーバーライドする以外にも、モジュールが複数回ロードされることを説明できるメカニズムはありますか?

答えて

22

モジュールがパスで2回見つかった場合、Pythonモジュールを2回インポートすることができます。

  • のsrc/
    • パッケージ1/
      • spam.py
      • eggs.py
:たとえば、あなたのプロジェクトがそうのようにレイアウトされていると言います

PYTHONPATH(sys.path)にsrcとsrc/pacが含まれているとしますkage1:その場合は

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

、あなたはこのように二回同じモジュールをインポートすることができます:

from package1 import spam 
import spam 

とPythonは、彼らが異なるモジュールだと思います。それは何が起こっているのですか?

また、(この質問を検索するユーザーのための)以下の説明では、最初のインポートの途中で例外がある場合、モジュールを2回インポートできる別の方法があります。たとえば、迷惑メールを迷惑メールにインポートしても、卵をインポートすると、モジュール内の例外が返されますが、再度インポートすることができます。

+0

これは良い点ですが、私はこの場合に起こっていることではないと思います。スタックトレースでわかるように、モジュールは両方の場合に同じステートメントでインポートされます: "import TiledConvC3D" –

+3

インポートが途中で初めて失敗する可能性はありますか?たとえば、モジュールのインポートの途中で例外があるとしますか? –

+0

はい、これが問題でした。私はtry文の中でインポートが許可されていることに気づいていませんでした。 –

関連する問題