Da dove viene inizializzato sys.path di Python?


111

Da dove viene inizializzato sys.path di Python?

UPD : Python sta aggiungendo alcuni percorsi prima di fare riferimento a PYTHONPATH:

    >>> 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']

Il mio PYTHONPATH è:

    PYTHONPATH=c:\testdir

Mi chiedo da dove vengano quei percorsi prima di quelli di PYTHONPATH?

Risposte:



77

Python si sforza davvero di impostare in modo intelligente sys.path. Il modo in cui è impostato può diventare davvero complicato . La seguente guida è un po 'incompleto, guida annacquata, in qualche modo, sbagliato, ma si spera-utili per il rango e file python programmatore di ciò che accade quando le figure di pitone che cosa da usare come i valori iniziali di sys.path, sys.executable, sys.exec_prefix, e sys.prefixsu una normale installazione di Python.

Innanzitutto, python fa del suo meglio per capire la sua effettiva posizione fisica nel filesystem in base a ciò che gli dice il sistema operativo. Se il sistema operativo dice che "python" è in esecuzione, si trova in $ PATH. Risolve tutti i collegamenti simbolici. Una volta eseguita questa operazione, il percorso dell'eseguibile che trova viene utilizzato come valore per sys.executable, senza se e senza ma.

Successivamente, determina i valori iniziali per sys.exec_prefixe sys.prefix.

Se c'è un file chiamato pyvenv.cfgnella stessa directory sys.executableo una directory in alto, Python lo guarda. Sistemi operativi diversi fanno cose diverse con questo file.

Uno dei valori in questo file di configurazione che Python cerca è l'opzione di configurazione home = <DIRECTORY>. Python userà questa directory invece della directory che la contiene sys.executable quando imposta dinamicamente il valore iniziale di sys.prefixlater. Se l' applocal = trueimpostazione appare nel pyvenv.cfgfile su Windows, ma non l' home = <DIRECTORY>impostazione, sys.prefixverrà impostata sulla directory contenente sys.executable.

Successivamente, PYTHONHOMEviene esaminata la variabile di ambiente. Su Linux e Mac sys.prefixe sys.exec_prefixsono impostati sulla PYTHONHOMEvariabile di ambiente, se esistente, sostituendo qualsiasi home = <DIRECTORY>impostazione in pyvenv.cfg. In Windows, sys.prefixed sys.exec_prefixè impostato al PYTHONHOMEvariabile d'ambiente, se esiste, a meno che un home = <DIRECTORY>ambiente è presente in pyvenv.cfg, che viene utilizzato invece.

Altrimenti, questi sys.prefixe sys.exec_prefixsi trovano camminando all'indietro dalla posizione di sys.executable, o dalla homedirectory fornita da pyvenv.cfgse esiste.

Se il file lib/python<version>/dyn-loadsi trova in quella directory o in una delle sue directory padre, quella directory è impostata per essere sys.exec_prefixsu Linux o Mac. Se il file lib/python<version>/os.pysi trova nella directory o in una delle sue sottodirectory, tale directory è impostata sys.prefixsu Linux, Mac e Windows, con sys.exec_prefixlo stesso valore di sys.prefixWindows. L'intero passaggio viene saltato su Windows se applocal = trueè impostato. sys.executableViene utilizzata la directory di oppure, se homeimpostata in pyvenv.cfg, viene utilizzata al posto del valore iniziale di sys.prefix.

Se non riesce a trovare questi file "punto di riferimento" o sys.prefixnon è stato ancora trovato, python si imposta sys.prefixsu un valore di "riserva". Linux e Mac, ad esempio, utilizzano valori predefiniti precompilati come valori di sys.prefixe sys.exec_prefix. Windows attende fino a quando non sys.pathviene completamente individuato per impostare un valore di fallback per sys.prefix.

Quindi, (quello che stavate tutti aspettando), python determina i valori iniziali in cui devono essere contenuti sys.path.

  1. La directory dello script in cui è in esecuzione python viene aggiunta sys.path. Su Windows, questa è sempre la stringa vuota, che dice a Python di utilizzare invece il percorso completo in cui si trova lo script.
  2. Il contenuto della variabile d'ambiente PYTHONPATH, se impostata, viene aggiunto a sys.path, a meno che tu non sia su Windows e applocalsia impostato su true in pyvenv.cfg.
  3. Il percorso del file zip, che si trova <prefix>/lib/python35.zipsu Linux / Mac e os.path.join(os.dirname(sys.executable), "python.zip")su Windows, viene aggiunto a sys.path.
  4. Se su Windows e non è applocal = truestato impostato alcun pyvenv.cfg, HK_CURRENT_USER\Software\Python\PythonCore\<DLLVersion>\PythonPath\viene aggiunto il contenuto delle sottochiavi della chiave di registro , se presente.
  5. Se su Windows e no è applocal = truestato impostato pyvenv.cfge sys.prefixnon è stato possibile trovarlo, viene aggiunto il contenuto principale della chiave di registro HK_CURRENT_USER\Software\Python\PythonCore\<DLLVersion>\PythonPath\, se esiste;
  6. Se su Windows e non è applocal = truestato impostato alcun pyvenv.cfg, HK_LOCAL_MACHINE\Software\Python\PythonCore\<DLLVersion>\PythonPath\viene aggiunto il contenuto delle sottochiavi della chiave di registro , se presente.
  7. Se su Windows e no è applocal = truestato impostato pyvenv.cfge sys.prefixnon è stato possibile trovarlo, viene aggiunto il contenuto principale della chiave di registro HK_CURRENT_USER\Software\Python\PythonCore\<DLLVersion>\PythonPath\, se esiste;
  8. Se su Windows e PYTHONPATH non è stato impostato, il prefisso non è stato trovato e non erano presenti chiavi di registro, viene aggiunto il valore relativo in fase di compilazione di PYTHONPATH; in caso contrario, questo passaggio viene ignorato.
  9. I percorsi nella macro in fase di compilazione PYTHONPATH vengono aggiunti rispetto a quelli trovati dinamicamente sys.prefix.
  10. Su Mac e Linux, sys.exec_prefixviene aggiunto il valore di . Su Windows, sys.prefixviene aggiunta la directory che è stata utilizzata (o sarebbe stata utilizzata) per la ricerca dinamica .

In questa fase su Windows, se non è stato trovato alcun prefisso, allora python proverà a determinarlo cercando in tutte le directory sys.pathi file di riferimento, come ha cercato di fare con la directory di in sys.executableprecedenza, finché non trova qualcosa. In caso contrario, sys.prefixviene lasciato vuoto.

Alla fine, dopo tutto questo, Python carica il sitemodulo, che aggiunge altre cose a sys.path:

Inizia costruendo fino a quattro directory da una parte di testa e una di coda. Per la parte di testa utilizza sys.prefixe sys.exec_prefix; le teste vuote vengono saltate. Per la parte di coda, utilizza la stringa vuota e quindi lib/site-packages(su Windows) o lib/pythonX.Y/site-packages e quindi lib/site-python(su Unix e Macintosh). Per ciascuna delle distinte combinazioni testa-coda, vede se si riferisce a una directory esistente e, in tal caso, la aggiunge a sys.path e controlla anche il percorso appena aggiunto per i file di configurazione.


1
Nonostante quello che dicono i suoi documenti, sys.executablepuò essere un collegamento simbolico o in realtà può essere qualsiasi cosa se argv[0]contiene barre. Il percorso effettivo dell'eseguibile (dalla execv(path, argv)chiamata) non viene utilizzato.
jfs

1
Per quanto riguarda il tuo primo punto per sys.pathWindows 10: ottengo sempre il percorso completo della mia directory di script come sys.path [0] (non cwd ''). Dovresti essere in grado di eseguire qualcosa comepython some\other\path\than\cwd\main.py
ford04

Sono d'accordo con @ ford04. Il punto 1 non è corretto: su Windows la directory dello script viene aggiunta a sys.path, non un percorso vuoto, né cwd. Questo è in varie installazioni di Python 3.x.
gwideman

1
Wow, è fantastico! Ho visto circa altre 10 domande e risposte prima di incappare in questa, la "verità", anche se stai umiliando ammettendo di non avere proprio tutto.
Mike Williamson

1
Vorrei aggiungere che i file rilevanti in site-packageshanno .pthe .egg-linksuffissi.
florisla
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.