2015-07-08 9 views
11

Recentemente ho riscontrato un problema con un ImportError python, in cui è stato rilevato il modulo quando è in esecuzione sul mio computer locale ma non trovato sul server CI. Ho risolto questo problema scambiando sys.path.append(path) nel mio script con sys.path.insert(0, path) dove path è il percorso del modulo di stringa.Effetto dell'utilizzo di sys.path.insert (0, path) e sys.path (append) durante il caricamento dei moduli

Poiché questo è il mio modulo e non un pacchetto installato (related question), perché l'ordine dei percorsi risolve questo problema?

+0

Possibile duplicato di [Perché utilizzare sys.path.append (percorso) anziché sys.path.insert (1, percorso)?] (Http://stackoverflow.com/questions/10095037/why-use-sys- percorso-appendpath-invece-di-sys-path-insert1-path) – CrandellWS

risposta

9

Poiché python controlla le directory in ordine sequenziale a partire dalla prima directory nell'elenco sys.path, fino a trovare il file .py che cercava.

Idealmente, la directory corrente o la directory dello script è il primo sempre il primo elemento nell'elenco, a meno che non lo modifichi, come hai fatto tu. Da documentation -

As initialized upon program startup, the first item of this list, path[0], is the directory containing the script that was used to invoke the Python interpreter. If the script directory is not available (e.g. if the interpreter is invoked interactively or if the script is read from standard input), path[0] is the empty string, which directs Python to search modules in the current directory first. Notice that the script directory is inserted before the entries inserted as a result of PYTHONPATH.

Quindi, molto probabilmente, si ha un file .py con lo stesso nome del modulo si stava tentando di importare, nella directory corrente (in cui lo script è stato eseguito da).

Inoltre, una cosa da notare su ImportError s, diciamo l'errore di importazione dice - ImportError: No module named main - non significa la main.py viene sovrascritto, non se questo è stato sovrascritto non avremmo avendo edizioni che provano a leggerlo. Alcuni moduli sopra questo sono stati sovrascritti con un. py o qualche altro file.

Esempio -

mia struttura di directory sembra -

- test 
    - shared 
     - __init__.py 
     - phtest.py 
    - testmain.py 

Ora Da testmain.py, chiamo from shared import phtest, funziona benissimo.

Ora lascia dire introduco uno shared.py in test directory`, ad esempio -

- test 
    - shared 
     - __init__.py 
     - phtest.py 
    - testmain.py 
    - shared.py 

Ora, quando provo a fare from shared import phtest da testmain.py, mi metterò l'errore -

ImportError: cannot import name 'phtest' 

Come puoi vedere sopra, il file che causa il problema è shared.py, non phtest.py.

+0

Il mio modulo era qualcosa.main, ho provato a cambiarlo in qualcosa.engine per vedere se questo era il problema, tuttavia avevo ancora l'ImportError, questo mi fa penso che non fosse il nome di un modulo/conflitto di file. –

+0

qual è stato l'errore di importazione? –

+1

L'ultima riga del traceback era "ImportError: No module named main" –

6

Sono abbastanza un principiante in Python e ho trovato la risposta di Anand era molto buona ma piuttosto complicato per me, quindi cerco di riformulare:

1) insert e append metodi non sono specifici per sys.path e come in altre lingue aggiungono un elemento in un elenco o matrice e:
* append(item) aggiungere item alla fine della lista,
* insert(n, item) inserisce il item nella posizione n nella lista (0 all'inizio, 1 dopo il primo elemento, ecc ...).

2) Come ha detto Anand, cerca pitone i file di importazione in ogni directory del percorso nell'ordine del percorso, in modo da:
* Se non si hanno le collisioni nome del file, l'ordine del percorso non ha alcun impatto,
* Se si prende in considerazione una funzione già definita nel percorso e si utilizza append per aggiungere il percorso, non si otterrà la funzione ma quella predefinita.

Ma penso che sia meglio utilizzare append e non insert per non sovraccaricare il comportamento standard di Python e utilizzare nomi non ambigui per i propri file e metodi.

Problemi correlati