2009-12-12 10 views
62

Un altro sviluppatore e non sono d'accordo sull'utilizzo di PYTHONPATH o sys.path per consentire a Python di trovare un pacchetto Python in una directory utente (ad es. Sviluppo).PYTHONPATH vs. sys.path

abbiamo un progetto Python con una tipica struttura di directory:

Project 
    setup.py 
    package 
     __init__.py 
     lib.py 
     script.py 

In script.py, abbiamo bisogno di fare import package.lib. Quando il pacchetto è installato nei pacchetti del sito, script.py può trovare package.lib.

Quando si lavora da una directory utente, tuttavia, è necessario fare qualcos'altro. La mia soluzione è impostare il mio PYTHONPATH per includere "~/Project". Un altro sviluppatore vuole mettere questa riga di codice all'inizio del script.py:

sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) 

Così che Python riesce a trovare la copia locale del package.lib.

Penso che questa sia una cattiva idea, in quanto questa linea è utile solo per gli sviluppatori o le persone che corrono da una copia locale, ma non posso dare una buona ragione per cui è una cattiva idea.

Dovremmo usare PYTOHNPATH, sys.path o va bene?

+1

Sembra che i voti e le risposte siano divisi in modo abbastanza uniforme con una leggera inclinazione verso l'uso di PYTHON_PATH anche se questo potrebbe essere il rumore di campionamento o il biasing non intenzionale dalla domanda. – AJP

risposta

37

Se l'unico motivo per modificare il percorso è per gli sviluppatori che lavorano dalla loro struttura di lavoro, è necessario utilizzare uno strumento di installazione per configurare il proprio ambiente. virtualenv è molto popolare, e se stai usando setuptools, puoi semplicemente eseguire setup.py develop per semi-installare l'albero di lavoro nella tua attuale installazione di Python.

2

Penso che in questo caso usare PYTHONPATH sia una cosa migliore, soprattutto perché non introduce (discutibile) codice non necessario.

Dopo tutto, se si pensa di esso, il tuo utente non ha bisogno che sys.path cosa, perché il pacchetto otterrà installato in site-packages, perché si prevede di utilizzare un sistema di confezionamento.

Se l'utente sceglie di eseguire da una "copia locale", come si chiama, allora ho osservato, che la prassi normale è dichiarare, che il pacchetto deve essere aggiunto manualmente a PYTHONPATH, se utilizzato all'esterno i pacchetti del sito.

32

Odio PYTHONPATH. Lo trovo fragile e fastidioso da impostare per utente (in particolare per gli utenti daemon) e tenere traccia delle cartelle del progetto che si muovono. Preferirei piuttosto impostare sys.path negli script di richiamo per progetti standalone.

Tuttavia sys.path.append non è il modo per farlo. È possibile ottenere facilmente duplicati e non risolve i file .pth. Migliore (e più leggibile): site.addsitedir.

E script.py normalmente non è il posto più appropriato per farlo, in quanto è all'interno del pacchetto che si desidera rendere disponibile sul percorso. I moduli di libreria non dovrebbero certamente toccare direttamente sys.path. Invece, normalmente avresti un hashbanged-script al di fuori del pacchetto che usi per istanziare ed eseguire l'app, ed è in questo banale script wrapper che inserisci dettagli di distribuzione come sys.path -frobbing.

+10

Il problema con 'site.addsitedir' è che fa un' append' su 'sys.path', il che significa che un pacchetto installato avrà la precedenza sul pacchetto locale in fase di sviluppo (e che potrebbe derivarne un taglio di capelli). 'sys.path.insert (0 ...' è necessario per superare questo. –

+3

@EliBendersky: dovrebbe essere 'sys.path.insert (1'. http://stackoverflow.com/q/10095037/125507 – endolith

4

Insieme con i molti altri motivi già citati, si potrebbe anche puntare outh che hard-codifica

sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

è fragile perché presume la posizione di script.py - funzionerà solo se lo script .py si trova in Project/package. Si romperà se un utente decide di spostare/copiare/symlink script.py (quasi) da qualsiasi altra parte.

7

In generale, prenderei in considerazione l'impostazione di una variabile di ambiente (come PYTHONPATH) come una cattiva pratica. Mentre questo potrebbe andare bene per un debug one-off, ma usando questo come
una pratica regolare potrebbe non essere una buona idea.

L'utilizzo della variabile di ambiente porta a situazioni come "funziona per me" quando alcuni uno
segnalano problemi nel codice di base. Inoltre si potrebbe portare la stessa pratica con l'ambiente di test , portando a situazioni come i test che funzionano bene per uno specifico sviluppatore ma probabilmente fallendo quando qualcuno lancia i test.

Problemi correlati