2011-01-25 16 views
11

Per quanto ho capito, un modulo python non viene mai importato due volte, cioè il codice nel modulo viene eseguito solo la prima volta che viene importato. Le istruzioni di importazione successive aggiungono semplicemente il modulo all'ambito dell'importazione.Cosa potrebbe causare l'importazione di un modulo python due volte?

Ho un modulo chiamato "TiledConvC3D.py" che sembra essere stato importato più volte. Io uso pdb per stampare lo stack nella parte superiore del codice per questo modulo.

Ecco la fine della traccia dello stack dalla prima volta che si esegue il modulo:

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() 

Si va avanti deve essere eseguito più volte di più. Tuttavia, l'analisi di stack completo per la seconda volta viene chiamata non mostra alcuna chiamata a reload, quindi queste esecuzioni non dovrebbero essere presenti:

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() 

Inoltre, posso controllare anche l'id di __builtin__.__import__. All'inizio del mio script principale, importare __builtin__ e stampare id(__builtin__.__import__) prima di fare qualsiasi altra importazione. Stampo anche id(__builtin__.import__) dall'interno del mio modulo che viene importato più volte e il valore dell'ID non cambia.

Esistono altri meccanismi oltre a chiamare ricaricare e sovrascrivere __builtin__.__import__ che potrebbe spiegare il caricamento del mio modulo più volte?

risposta

22

Un modulo Python può essere importato due volte se il modulo viene trovato due volte nel percorso. Ad esempio, dire il progetto è presentato in questo modo:

  • src/
    • package1/
      • spam.py
      • eggs.py

Supponiamo che il tuo PYTHONPATH (sys.path) includa src e src/pac kage1:

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

Se questo è il caso, è possibile importare lo stesso modulo per due volte in questo modo:

from package1 import spam 
import spam 

e Python penserà che sono diversi moduli. E 'quello che sta succedendo?

Inoltre, per la discussione seguente (per gli utenti che cercano questa domanda), un altro modo in cui un modulo può essere importato due volte è se c'è un'eccezione a metà della prima importazione. Ad esempio, se lo spam importa uova, ma l'importazione di uova risulta in un'eccezione all'interno del modulo, può essere nuovamente importata.

+0

Questo è un buon punto, ma non penso che sia ciò che sta accadendo in questo caso. Come si può vedere nelle tracce dello stack, il modulo viene importato con la stessa istruzione in entrambi i casi: "import TiledConvC3D" –

+3

È possibile che l'importazione non funzioni a metà della prima volta? Ad esempio, forse se c'è un'eccezione a metà dell'importazione del modulo? –

+0

Sì, questo era il problema. Non mi ero reso conto che l'importazione era consentita all'interno delle dichiarazioni di prova. –

Problemi correlati