2011-01-25 62 views
11

據我所知,python模塊永遠不會被導入兩次,即模塊中的代碼只在第一次被導入時被執行。隨後的導入語句只是將該模塊添加到導入的範圍。什麼可能導致python模塊導入兩次?

我有一個名爲「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的值沒有改變。

除了調用重載和覆蓋__builtin__.__import__,還有其他的機制可以解釋我的模塊多次加載嗎?

回答

22

如果在路徑中找到兩次模塊,則可以導入Python模塊兩次。例如,假設你的項目佈局,像這樣:

  • 的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會認爲他們是不同的模塊。這是怎麼回事?

此外,根據下面的討論(用於搜索此問題的用戶),另一種模塊可以導入兩次的方式是在第一次導入中途出現異常。例如,如果垃圾郵件導入雞蛋,但導入雞蛋會導致模塊內的異常,則可以再次導入雞蛋。

+0

這是一個好點,但我不認爲這就是發生在這種情況。正如你可以在棧跟蹤中看到的那樣,在這兩種情況下模塊都被導入了相同的語句:「import TiledConvC3D」 – 2011-01-25 20:52:50