Warum sollte sys.path.append (Pfad) anstelle von sys.path.insert (1, Pfad) verwendet werden?

88

Bearbeiten: Basierend auf dem Kommentar eines Ulf Rompe ist es wichtig, dass Sie "1" anstelle von "0" verwenden , da Sie sonst sys.path unterbrechen .

Ich mache jetzt schon eine ganze Weile (über ein Jahr) Python und bin immer verwirrt darüber, warum die Leute empfehlen, dass Sie sys.path.append()statt verwenden sys.path.insert(). Lassen Sie mich demonstrieren.

Angenommen, ich arbeite an einem Modul namens PyWorkbooks (das auf meinem Computer installiert ist), aber gleichzeitig an einem anderen Modul (sagen wir PyJob), das PyWorkbooks enthält. Während ich an PyJob arbeite, finde ich Fehler in PyWorkbooks, die ich korrigiere, daher möchte ich eine Entwicklungsversion importieren.

Es gibt mehrere Möglichkeiten, an beiden zu arbeiten (ich könnte mein PyWorkbooks-Projekt beispielsweise in PyJob einfügen), aber manchmal muss ich trotzdem mit dem Pfad spielen. Allerdings kann ich nicht einfach tun , sys.path.append()um den Ordner , in dem PyWorkbooks an ist . Warum? Weil Python zuerst meine installierten PyWorkbooks findet!

Aus diesem Grund müssen Sie einen sys.path.insert (1, path_to_dev_pyworkbooks) ausführen.

Zusammenfassend:

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

oder:

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

Dies hat in der Vergangenheit einige Probleme für mich verursacht, und ich würde es wirklich begrüßen, wenn wir (als Community) anfangen würden zu empfehlen sys.path.insert(1, path), als ob Sie manuell einen Pfad einfügen. Ich denke, es ist sicher zu sagen, dass dies der gewünschte Pfad ist benutzen!

Oder habe ich etwas falsch? Es ist eine Frage, die mich manchmal stört und die ich offen haben wollte!

Garrett Berg
quelle
3
Ich habe es getan, sys.path.insert(1, dev_folder)aber es findet immer noch nicht das Dev-Modul und verwendet nur das installierte Modul. Wie behebe ich das?
Endolith

Antworten:

47

Wenn Sie mehrere Versionen eines Pakets / Moduls haben, müssen Sie virtualenv (Schwerpunkt Mine) verwenden:

virtualenv ist ein Tool zum Erstellen isolierter Python-Umgebungen.

Das grundlegende Problem, das angesprochen wird, sind Abhängigkeiten und Versionen sowie indirekte Berechtigungen. Stellen Sie sich vor, Sie haben eine Anwendung, die Version 1 von LibFoo benötigt, für eine andere Anwendung jedoch Version 2. Wie können Sie beide Anwendungen verwenden? Wenn Sie alles in /usr/lib/python2.7/site-packages(oder wie auch immer der Standardspeicherort Ihrer Plattform ist) installieren , kann es leicht zu einer Situation kommen, in der Sie unbeabsichtigt eine Anwendung aktualisieren, die nicht aktualisiert werden sollte.

Oder allgemeiner, was ist, wenn Sie eine Anwendung installieren und belassen möchten ? Wenn eine Anwendung funktioniert, kann jede Änderung in ihren Bibliotheken oder den Versionen dieser Bibliotheken die Anwendung beschädigen.

Was ist auch, wenn Sie keine Pakete im globalen site-packagesVerzeichnis installieren können ? Zum Beispiel auf einem gemeinsam genutzten Host.

In all diesen Fällen virtualenvkann Ihnen helfen. Es wird eine Umgebung erstellt, die über eigene Installationsverzeichnisse verfügt, die keine Bibliotheken für andere virtuelle Umgebungen freigeben (und optional auch nicht auf die global installierten Bibliotheken zugreifen).

Aus diesem Grund halten die Leute insert(0, es für falsch - es ist eine unvollständige Notlösung für das Problem der Verwaltung mehrerer Umgebungen.

agf
quelle
Danke, ich wusste vage, dass so etwas existiert, aber ich habe es bis jetzt noch nicht überprüft. Was ich damit tun müsste, ist, alles vom Interpreter in der virtuellen Umgebung auszuführen ... das könnte auch funktionieren. Vielen Dank!
Garrett Berg
1
Dies ist ein Vorschlag, der die Frage jedoch nicht direkt beantwortet (z. B. habe ich starke Gründe, sie nicht zu verwenden, virtualenvund suche tatsächlich nach der zugehörigen Antwort auf das OP)
javadba
@javadba Das mag für Ihren Fall zutreffen, aber die meisten Leute, die diese Frage stellen, sollten verwenden venv.
Agf
45

Wenn Sie sys.path.insert wirklich verwenden müssen, sollten Sie sys.path [0] unverändert lassen:

sys.path.insert(1, path_to_dev_pyworkbooks)

Dies kann wichtig sein, da Code von Drittanbietern möglicherweise von der Konformität der sys.path-Dokumentation abhängt :

Wie beim Programmstart initialisiert, ist das erste Element dieser Liste, Pfad [0], das Verzeichnis, das das Skript enthält, mit dem der Python-Interpreter aufgerufen wurde.

Ulf Rompe
quelle
13

Sie verwirren das Konzept des Anhängens und Voranstellens. Der folgende Code steht vor:

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

Es platziert die neuen Informationen am Anfang (genauer gesagt an zweiter Stelle) der Suchsequenz, die Ihr Dolmetscher durchlaufen wird. sys.path.append()setzt die Dinge ganz am Ende der Suchsequenz.

Es ist ratsam, dass Sie so etwas wie verwenden, virtualenvanstatt Ihre Paketverzeichnisse PYTHONPATHjedes Mal manuell in das zu codieren. Lesen Sie diese beiden Blogs, um verschiedene Ökosysteme einzurichten, die Ihre Site-Pakete und mögliche Versionen von Python trennen:

  1. Einführung in Python-Ökosysteme

  2. Bootstrapping von virtuellen Python-Umgebungen

Wenn Sie sich für den Weg zur Isolation der Umgebung entscheiden, profitieren Sie sicherlich von einem Blick auf virtualenvwrapper: http://www.doughellmann.com/docs/virtualenvwrapper/

samkhan13
quelle
1
Die Links "Einführung in Python-Ökosysteme", "Virtuelle Bootstrapping-Python-Umgebungen" wurden eingestellt. Bitte erwägen Sie, sie erneut zu beleben.
Pradeep Singh