Perché usare sys.path.append (path) invece di sys.path.insert (1, path)?


88

Modifica: in base al commento di Ulf Rompe, è importante che tu usi "1" invece di "0" , altrimenti interromperai sys.path .

Faccio python da un po 'di tempo ormai (più di un anno) e sono sempre confuso sul motivo per cui le persone consigliano di usare sys.path.append()invece di sys.path.insert(). Fammi dimostrare.

Diciamo che sto lavorando su un modulo chiamato PyWorkbooks (che è installato sul mio computer), ma contemporaneamente sto lavorando su un modulo diverso (diciamo PyJob) che incorpora PyWorkbooks. Mentre lavoro su PyJob trovo errori in PyWorkbooks che sto correggendo, quindi vorrei importare una versione di sviluppo.

Esistono diversi modi per lavorare su entrambi (ad esempio, potrei inserire il mio progetto PyWorkbooks all'interno di PyJob), ma a volte avrò ancora bisogno di giocare con il percorso. Tuttavia, non posso semplicemente fare un sys.path.append()alla cartella in cui si trova PyWorkbooks . Perché? Perché python troverà prima i miei PyWorkbook installati!

Questo è il motivo per cui devi fare un sys.path.insert (1, path_to_dev_pyworkbooks)

In sintesi:

sys.path.append(path_to_dev_pyworkbooks)
import PyWorkbooks # does NOT import dev pyworkbooks, imports installed one

o:

sys.path.insert(1, path_to_dev_pyworkbooks) # based on comments you should use **1 not 0**
import PyWorkbooks # imports correct file

Questo mi ha causato alcuni problemi in passato, e mi piacerebbe davvero che noi (come comunità) iniziassimo a consigliare sys.path.insert(1, path), come se stessi inserendo manualmente un percorso, penso sia sicuro dire che è il percorso che desideri usare!

O ho qualcosa che non va? È una domanda che a volte mi dà fastidio e la volevo allo scoperto!


3
L'ho fatto sys.path.insert(1, dev_folder)ma ancora non trova il modulo dev e utilizza solo il modulo installato. Come lo risolvo?
endolith

Risposte:


47

Se hai più versioni di un pacchetto / modulo, devi usare virtualenv (enfasi mia):

virtualenv è uno strumento per creare ambienti Python isolati.

Il problema di base che viene affrontato è una delle dipendenze, delle versioni e indirettamente delle autorizzazioni. Immagina di avere un'applicazione che richiede la versione 1 di LibFoo, ma un'altra applicazione richiede la versione 2. Come puoi utilizzare entrambe queste applicazioni? Se installi tutto in /usr/lib/python2.7/site-packages(o qualunque sia la posizione standard della tua piattaforma), è facile finire in una situazione in cui aggiorni involontariamente un'applicazione che non dovrebbe essere aggiornata.

O più in generale, cosa succede se si desidera installare un'applicazione e lasciarla così ? Se un'applicazione funziona, qualsiasi modifica alle sue librerie o alle versioni di tali librerie può interrompere l'applicazione.

Inoltre, cosa succede se non è possibile installare i pacchetti nella site-packagesdirectory globale ? Ad esempio, su un host condiviso.

In tutti questi casi, virtualenvpuò aiutarti. Crea un ambiente che ha le proprie directory di installazione, che non condivide le librerie con altri ambienti virtualenv (e opzionalmente non accede nemmeno alle librerie installate globalmente).

Ecco perché le persone considerano insert(0, sbagliato: è una soluzione provvisoria incompleta al problema della gestione di più ambienti.


Grazie, sapevo vagamente che esistesse qualcosa del genere, ma fino ad ora non l'ho verificato. Quindi quello che dovrei fare con questo è eseguire tutto dall'interprete nell'ambiente virtuale ... anche quello potrebbe funzionare. Grazie!
Garrett Berg

1
Questo è un suggerimento ma non risponde direttamente alla domanda (ad esempio, ho forti motivi per non usarlo virtualenve in realtà sto cercando la risposta associata
all'OP

@javadba Potrebbe essere vero per il tuo caso, ma la maggior parte delle persone che fanno questa domanda dovrebbe usare venv.
agf

46

Se hai davvero bisogno di usare sys.path.insert, considera di lasciare sys.path [0] così com'è:

sys.path.insert(1, path_to_dev_pyworkbooks)

Questo potrebbe essere importante poiché il codice di terze parti può fare affidamento sulla conformità della documentazione di sys.path :

Come inizializzato all'avvio del programma, il primo elemento di questo elenco, percorso [0], è la directory contenente lo script che è stato utilizzato per invocare l'interprete Python.


13

stai confondendo il concetto di aggiungere e anteporre. il codice seguente è anteposto:

sys.path.insert(1,'/thePathToYourFolder/')

pone le nuove informazioni all'inizio (beh, secondo, per essere precisi) della sequenza di ricerca che il tuo interprete eseguirà. sys.path.append()mette le cose alla fine della sequenza di ricerca.

è consigliabile utilizzare qualcosa di simile virtualenvinvece di codificare manualmente le directory dei pacchetti in PYTHONPATHogni momento. per impostare vari ecosistemi che separano i pacchetti del tuo sito e le possibili versioni di python, leggi questi due blog:

  1. introduzione agli ecosistemi Python

  2. avvio di ambienti virtuali Python

se decidi di spostarti lungo il percorso verso l'isolamento dell'ambiente, trarrai sicuramente vantaggio esaminando virtualenvwrapper: http://www.doughellmann.com/docs/virtualenvwrapper/


1
I collegamenti "introduzione agli ecosistemi python", "bootstrap degli ambienti virtuali python" sono stati ritirati, si prega di considerare di rivitalizzarli.
Pradeep Singh
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.