Woher wird Pythons sys.path initialisiert?

111

Woher wird Pythons sys.path initialisiert?

UPD : Python fügt einige Pfade hinzu, bevor auf PYTHONPATH verwiesen wird:

    >>> import sys
    >>> from pprint import pprint as p
    >>> p(sys.path)
    ['',
     'C:\\Python25\\lib\\site-packages\\setuptools-0.6c9-py2.5.egg',
     'C:\\Python25\\lib\\site-packages\\orbited-0.7.8-py2.5.egg',
     'C:\\Python25\\lib\\site-packages\\morbid-0.8.6.1-py2.5.egg',
     'C:\\Python25\\lib\\site-packages\\demjson-1.4-py2.5.egg',
     'C:\\Python25\\lib\\site-packages\\stomper-0.2.2-py2.5.egg',
     'C:\\Python25\\lib\\site-packages\\uuid-1.30-py2.5.egg',
     'C:\\Python25\\lib\\site-packages\\stompservice-0.1.0-py2.5.egg',
     'C:\\Python25\\lib\\site-packages\\cherrypy-3.0.1-py2.5.egg',
     'C:\\Python25\\lib\\site-packages\\pyorbited-0.2.2-py2.5.egg',
     'C:\\Python25\\lib\\site-packages\\flup-1.0.1-py2.5.egg',
     'C:\\Python25\\lib\\site-packages\\wsgilog-0.1-py2.5.egg',
     'c:\\testdir',
     'C:\\Windows\\system32\\python25.zip',
     'C:\\Python25\\DLLs',
     'C:\\Python25\\lib',
     'C:\\Python25\\lib\\plat-win',
     'C:\\Python25\\lib\\lib-tk',
     'C:\\Python25',
     'C:\\Python25\\lib\\site-packages',
     'C:\\Python25\\lib\\site-packages\\PIL',
     'C:\\Python25\\lib\\site-packages\\win32',
     'C:\\Python25\\lib\\site-packages\\win32\\lib',
     'C:\\Python25\\lib\\site-packages\\Pythonwin']

Mein PYTHONPATH ist:

    PYTHONPATH=c:\testdir

Ich frage mich, woher diese Wege vor PYTHONPATHs kommen.

Alex
quelle

Antworten:

77

Python ist wirklich bemüht, intelligent einzustellen sys.path. Wie es eingestellt ist, kann sehr kompliziert werden . Die folgende Anleitung ist eine abgeschwächte, etwas-unvollständig, etwas-falsch, aber hoffentlich-nützliche Leitfaden für den Rang-und-Datei Python - Programmierer von dem, was passiert , wenn Python Zahlen heraus , was als verwenden Anfangswerte von sys.path, sys.executable, sys.exec_prefixund sys.prefixbei einer normalen Python-Installation.

Zunächst bemüht sich Python nach besten Kräften, den tatsächlichen physischen Speicherort im Dateisystem anhand der Angaben des Betriebssystems zu ermitteln. Wenn das Betriebssystem nur sagt, dass "Python" ausgeführt wird, befindet es sich in $ PATH. Es löst alle symbolischen Links auf. Sobald dies geschehen ist, wird der Pfad der gefundenen ausführbaren Datei als Wert für sys.executableno ifs, ands oder buts verwendet.

Als nächstes werden die Anfangswerte für sys.exec_prefixund bestimmt sys.prefix.

Wenn sich eine Datei pyvenv.cfgim selben Verzeichnis wie sys.executableoder in einem Verzeichnis befindet, wird sie von Python angezeigt. Verschiedene Betriebssysteme machen mit dieser Datei verschiedene Dinge.

Einer der Werte in dieser Konfigurationsdatei, nach denen Python sucht, ist die Konfigurationsoption home = <DIRECTORY>. Python verwendet dieses Verzeichnis anstelle des Verzeichnisses, sys.executable in dem der Anfangswert von sys.prefixspäter dynamisch festgelegt wird . Wenn die applocal = trueEinstellung in der pyvenv.cfgDatei unter Windows angezeigt wird , jedoch nicht die home = <DIRECTORY>Einstellung, sys.prefixwird sie auf das Verzeichnis festgelegt, das sie enthält sys.executable.

Als nächstes wird die PYTHONHOMEUmgebungsvariable untersucht. Unter Linux und Mac sys.prefixund sys.exec_prefixauf die PYTHONHOMEUmgebungsvariable gesetzt, falls vorhanden, ersetzt sie alle home = <DIRECTORY>Einstellungen in pyvenv.cfg. Unter Windows sys.prefixund sys.exec_prefixwird auf die PYTHONHOMEUmgebungsvariable festgelegt, sofern vorhanden, es sei denn, in ist eine home = <DIRECTORY>Einstellung vorhanden pyvenv.cfg, die stattdessen verwendet wird.

Andernfalls werden diese sys.prefixund sys.exec_prefixgefunden, indem Sie vom Speicherort sys.executableoder dem homevon pyvenv.cfggegebenenfalls angegebenen Verzeichnis rückwärts gehen .

Wenn sich die Datei lib/python<version>/dyn-loadin diesem Verzeichnis oder einem der übergeordneten Verzeichnisse befindet, ist dieses Verzeichnis sys.exec_prefixauf Linux oder Mac eingestellt. Wenn sich die Datei lib/python<version>/os.pyim Verzeichnis oder in einem seiner Unterverzeichnisse befindet, wird dieses Verzeichnis sys.prefixauf Linux, Mac und Windows festgelegt, wobei sys.exec_prefixderselbe Wert wie sys.prefixunter Windows festgelegt wird. Dieser gesamte Schritt wird unter Windows übersprungen, wenn applocal = truefestgelegt. Entweder wird das Verzeichnis von sys.executableverwendet, oder, falls homefestgelegt pyvenv.cfg, wird es stattdessen für den Anfangswert von verwendet sys.prefix.

Wenn diese "Landmark" -Dateien sys.prefixnicht gefunden werden können oder noch nicht gefunden wurden, setzt Python sys.prefixauf einen "Fallback" -Wert. Linux und Mac verwenden beispielsweise vorkompilierte Standardeinstellungen als Werte für sys.prefixund sys.exec_prefix. Windows wartet, bis sys.pathes vollständig herausgefunden ist, um einen Fallback-Wert für festzulegen sys.prefix.

Dann bestimmt Python (worauf Sie alle gewartet haben) die Anfangswerte, in denen enthalten sein soll sys.path.

  1. Das Verzeichnis des Skripts, das Python ausführt, wird hinzugefügt sys.path. Unter Windows ist dies immer die leere Zeichenfolge, die Python anweist, stattdessen den vollständigen Pfad zu verwenden, in dem sich das Skript befindet.
  2. Der Inhalt der Umgebungsvariablen PYTHONPATH wird, falls festgelegt, hinzugefügt sys.path, es sei denn, Sie arbeiten unter Windows und applocalsind auf true in festgelegt pyvenv.cfg.
  3. Der Zip-Dateipfad, der sich <prefix>/lib/python35.zipunter Linux / Mac und os.path.join(os.dirname(sys.executable), "python.zip")Windows befindet, wird hinzugefügt sys.path.
  4. Wenn unter Windows und no applocal = truefestgelegt wurde pyvenv.cfg, wird der Inhalt der Unterschlüssel des Registrierungsschlüssels HK_CURRENT_USER\Software\Python\PythonCore\<DLLVersion>\PythonPath\hinzugefügt, falls vorhanden.
  5. Wenn unter Windows und no applocal = truefestgelegt pyvenv.cfgwurde und sys.prefixnicht gefunden werden konnte, wird der Kerninhalt des Registrierungsschlüssels HK_CURRENT_USER\Software\Python\PythonCore\<DLLVersion>\PythonPath\hinzugefügt, sofern vorhanden.
  6. Wenn unter Windows und no applocal = truefestgelegt wurde pyvenv.cfg, wird der Inhalt der Unterschlüssel des Registrierungsschlüssels HK_LOCAL_MACHINE\Software\Python\PythonCore\<DLLVersion>\PythonPath\hinzugefügt, falls vorhanden.
  7. Wenn unter Windows und no applocal = truefestgelegt pyvenv.cfgwurde und sys.prefixnicht gefunden werden konnte, wird der Kerninhalt des Registrierungsschlüssels HK_CURRENT_USER\Software\Python\PythonCore\<DLLVersion>\PythonPath\hinzugefügt, sofern vorhanden.
  8. Wenn unter Windows und PYTHONPATH nicht festgelegt wurde, das Präfix nicht gefunden wurde und keine Registrierungsschlüssel vorhanden waren, wird der relative Wert für die Kompilierungszeit von PYTHONPATH hinzugefügt. Andernfalls wird dieser Schritt ignoriert.
  9. Pfade im Makro PYTHONPATH zur Kompilierungszeit werden relativ zu den dynamisch gefundenen hinzugefügt sys.prefix.
  10. Unter Mac und Linux wird der Wert von sys.exec_prefixhinzugefügt. Unter Windows wird das Verzeichnis sys.prefixhinzugefügt , nach dem dynamisch gesucht wurde (oder verwendet wurde) .

Wenn zu diesem Zeitpunkt unter Windows kein Präfix gefunden wurde, versucht Python, es zu ermitteln, indem alle Verzeichnisse sys.pathnach den Orientierungspunktdateien durchsucht werden, wie dies beim sys.executablevorherigen Verzeichnis der Fall war, bis etwas gefunden wird. Wenn dies nicht der Fall sys.prefixist, bleibt es leer.

Nach all dem lädt Python schließlich das siteModul, das noch weitere Dinge hinzufügt sys.path:

Zunächst werden bis zu vier Verzeichnisse aus einem Kopf- und einem Endteil erstellt. Für den Kopfteil verwendet es sys.prefixund sys.exec_prefix; leere Köpfe werden übersprungen. Für den Endteil wird die leere Zeichenfolge verwendet und dann lib/site-packages(unter Windows) oder lib/pythonX.Y/site-packages und dann lib/site-python(unter Unix und Macintosh). Für jede der verschiedenen Head-Tail-Kombinationen wird geprüft, ob sie auf ein vorhandenes Verzeichnis verweist, und wenn ja, wird sie zu sys.path hinzugefügt und der neu hinzugefügte Pfad auf Konfigurationsdateien überprüft.

djhaskin987
quelle
1
Ungeachtet dessen, was in den Dokumenten steht, sys.executablekann es sich um einen Symlink handeln, oder es kann sich um etwas handeln, argv[0]das Schrägstriche enthält. Der tatsächliche Pfad zur ausführbaren Datei (vom execv(path, argv)Aufruf) wird nicht verwendet.
JFS
1
Zu Ihrem ersten Punkt für sys.pathWindows 10: Ich erhalte immer den vollständigen Pfad meines Skriptverzeichnisses als sys.path [0] (nicht cwd ''). Sie sollten in der Lage sein, etwas wiepython some\other\path\than\cwd\main.py
ford04
Ich stimme @ ford04 zu. Punkt 1 ist falsch: Unter Windows wird das Verzeichnis des Skripts zu sys.path hinzugefügt, weder zu einem leeren Pfad noch zu cwd. Dies ist in verschiedenen Python 3.x-Installationen.
Gwideman
1
Wow, das ist großartig! Ich habe ungefähr 10 andere Fragen und Antworten gesehen, bevor ich auf diese "Wahrheit" gestoßen bin, obwohl Sie demütig zugeben, dass Sie nicht alles haben.
Mike Williamson
1
Ich würde hinzufügen, dass relevante Dateien in site-packageshaben .pthund .egg-linkSuffixe.
Florida