2010-06-29 10 views
55

Mi sono appena iscritto a un progetto con una base di codice esistente piuttosto grande. Sviluppiamo in linux e non usiamo e IDE. Corriamo attraverso la riga di comando. Sto cercando di capire come ottenere Python per cercare il percorso giusto quando eseguo i moduli del progetto. Per esempio, quando corro qualcosa come:Espandi percorso di ricerca Python ad altra origine

python someprojectfile.py 

ottengo

ImportError: no module named core.'somemodule' 

ottengo questo per tutti i miei importazioni Penso che sia un problema con il percorso.

TLDR:

Come faccio ad avere Python per cercare ~/codez/project/ e tutti i file e le cartelle per i file * .py durante istruzioni import.

risposta

95

ci sono alcuni modi possibili per farlo:

  • Impostare la variabile di ambiente PYTHONPATH a una lista separata da due punti di directory per la ricerca di moduli importati.
  • Nel programma, utilizzare sys.path.append('/path/to/search') per aggiungere i nomi delle directory che si desidera che Python cerchi i moduli importati. sys.path è solo l'elenco delle directory che Python cerca ogni volta che viene chiesto di importare un modulo, e puoi modificarlo secondo necessità (anche se non ti consiglierei di rimuovere nessuna delle directory standard!). Qualsiasi directory inserita nella variabile di ambiente PYTHONPATH verrà inserita in sys.path all'avvio di Python.
  • Utilizzare site.addsitedir per aggiungere una directory a sys.path. La differenza tra questa e la semplice aggiunta è che quando si utilizza addsitedir, si cercano anche i file .pth all'interno di quella directory e li si utilizza per aggiungere eventualmente directory aggiuntive a sys.path in base al contenuto dei file. Vedi la documentazione per maggiori dettagli.

Quale di questi si desidera utilizzare dipende dalla situazione. Ricorda che quando si distribuisce il progetto ad altri utenti, di solito lo installano in modo tale che i file di codice Python vengano automaticamente rilevati dall'importatore di Python (cioè i pacchetti vengono solitamente installati nella directory site-packages), quindi se si scherza con sys.path in il tuo codice, che potrebbe non essere necessario e potrebbe anche avere effetti negativi quando quel codice viene eseguito su un altro computer. Per lo sviluppo, mi permetto di indovinare che l'impostazione di PYTHONPATH è di solito il modo migliore per andare.

Tuttavia, quando si utilizza qualcosa che appena viene eseguito sul proprio computer (o quando si hanno configurazioni non standard, ad esempio, a volte in contesti web app), non è del tutto insolita per fare qualcosa di simile

from os.path import dirname 
sys.path.append(dirname(__file__)) 
+0

Quindi, se avessi avuto bisogno di dire 15 sottodirectory, dovrei aggiungere ognuna singolarmente? – themaestro

+0

e potresti fornire un esempio di un argomento della riga di comando per modificare PYTHONPATH? – themaestro

+2

Per impostare 'PYTHONPATH': in' .bashrc' o qualunque altro file di avvio usi la shell (se non è Bash), scrivi 'export PYTHONPATH = $ PYTHONPATH: $ HOME/codez/project'. Ma se hai un sacco di sottodirectory, creo un file '.pth' e uso' site.addsitedir'. Puoi creare un modulo 'sitecustomize' che possa chiamare la funzione per te; prova a metterlo su '~/.local/lib/python2.6/sitecustomize.py' (sostituisci la tua versione di Python) così si spera che venga automaticamente importato. –

9

Si dovrebbe anche leggere sui pacchetti Python qui: http://docs.python.org/tutorial/modules.html.

Dal tuo esempio, direi che hai davvero un pacchetto a ~/codez/project. Il file __init__.py in una directory python mappa una directory in uno spazio dei nomi. Se tutte le sottodirectory hanno tutte un file __init__.py, è sufficiente aggiungere la directory di base al numero PYTHONPATH.Per esempio:

PYTHONPATH = $ PYTHONPATH: $ HOME/adaifotis/progetto

Oltre a testare la variabile d'ambiente PYTHONPATH, come spiega David, è possibile verificare in pitone come questo:

$ python 
>>> import project      # should work if PYTHONPATH set 
>>> import sys 
>>> for line in sys.path: print line # print current python path 

...

+0

Puoi mettere il tuo '__init __. Py' nei backtick per chiarire che intendi veramente' __init __. Py', al contrario di 'init.py'. Giusto per evitare di confondere i principianti. :) – antred

2

ho letto questa domanda cerca di una risposta, e non piaceva nessuno di loro.

Così ho scritto una soluzione rapida e sporca. Basta mettere questo da qualche parte sul vostro sys.path, e sarà aggiungere qualsiasi directory sotto folder (dalla directory di lavoro corrente), o sotto abspath:

#using.py 

import sys, os.path 

def all_from(folder='', abspath=None): 
    """add all dirs under `folder` to sys.path if any .py files are found. 
    Use an abspath if you'd rather do it that way. 

    Uses the current working directory as the location of using.py. 
    Keep in mind that os.walk goes *all the way* down the directory tree. 
    With that, try not to use this on something too close to '/' 

    """ 
    add = set(sys.path) 
    if abspath is None: 
     cwd = os.path.abspath(os.path.curdir) 
     abspath = os.path.join(cwd, folder) 
    for root, dirs, files in os.walk(abspath): 
     for f in files: 
      if f[-3:] in '.py': 
       add.add(root) 
       break 
    for i in add: sys.path.append(i) 

>>> import using, sys, pprint 
>>> using.all_from('py') #if in ~, /home/user/py/ 
>>> pprint.pprint(sys.path) 
[ 
#that was easy 
] 

E mi piace perché posso avere una cartella per un po ' strumenti casuali e non farli essere una parte di pacchetti o qualcosa, e ancora ottenere l'accesso ad alcuni (o tutti) di loro in un paio di linee di codice.

1

Il modo più semplice che trovo è quello di creare un file "any_name.pth" e inserirlo nella cartella "\ Lib \ site-packages". Dovresti trovare quella cartella ovunque sia installato python.

In tale file, inserire un elenco di directory in cui si desidera conservare i moduli per l'importazione. Per esempio, fare una linea in quel file come questo:

C: \ Users \ esempio ... \ esempio

Sarete in grado di dire che funziona eseguendo questo in python:

import sys 
for line in sys: print line 

Vedrai la tua directory stampata, tra le altre da dove puoi anche importare. Ora è possibile importare un file "mymodule.py" che si trova nella directory facilmente come:

import mymodule 

Questo non importare le sottocartelle. Per questo puoi immaginare di creare uno script python per creare un file .pth contenente tutte le sottocartelle di una cartella che definisci. Hanno forse avviato all'avvio.

1

So che questo thread è un po 'vecchio, ma mi ci è voluto del tempo per arrivare al cuore di questo, quindi ho voluto condividere.

Nel mio progetto, avevo lo script principale in una directory padre e, per differenziare i moduli, inserivo tutti i moduli di supporto in una sottocartella chiamata "moduli". Nel mio script principale, a importare questi moduli come questo (per un modulo chiamato report.py):

da modules.report rapporto di importazione, reportError

Se chiamo il mio script principale, questo funziona. Tuttavia, ho voluto mettere alla prova ogni modulo includendo un main() in ciascuna, e chiamando ogni direttamente, come:

moduli Python \ report.py

Ora Python si lamenta che non riesce a trovare "un modulo chiamati moduli ". La chiave qui è che, per impostazione predefinita, Python include la cartella dello script nel suo percorso di ricerca, MA NON LA CWD. Quindi, ciò che questo errore dice, in realtà, è "Non riesco a trovare una sottocartella di moduli".Il motivo è perché non esiste una sottodirectory "modules" dalla directory in cui risiede il modulo report.py.

trovo che la soluzione più pulita a questo è di aggiungere il CWD in Python percorso di ricerca includendo questo in alto: ("")

import sys

sys.path.append

Ora Python cerca CWD (directory corrente), trova la sottocartella "modules" e tutto va bene.

Problemi correlati