D'où est initialisé sys.path de Python?


111

D'où est initialisé sys.path de Python?

UPD : Python ajoute quelques chemins avant de faire référence à 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']

Mon PYTHONPATH est:

    PYTHONPATH=c:\testdir

Je me demande d'où viennent ces chemins avant ceux de PYTHONPATH?

Réponses:



77

Python s'efforce vraiment de définir intelligemment sys.path. La façon dont il est défini peut devenir vraiment compliqué . Le guide suivant est édulcorée, quelque peu incomplète, quelque peu de mal, mais Guide , espérons-utile pour le rang et le fichier programmeur python de ce qui se passe lorsque les chiffres de python ce qu'il faut utiliser comme valeurs initiales de sys.path, sys.executable, sys.exec_prefix, et sys.prefixsur une installation python normale .

Premièrement, python fait de son mieux pour déterminer son emplacement physique réel sur le système de fichiers en fonction de ce que le système d'exploitation lui dit. Si le système d'exploitation dit simplement que "python" est en cours d'exécution, il se trouve dans $ PATH. Il résout tous les liens symboliques. Une fois qu'il a fait cela, le chemin de l'exécutable qu'il trouve est utilisé comme valeur pour sys.executable, no ifs, ands, or mais.

Ensuite, il détermine les valeurs initiales de sys.exec_prefixet sys.prefix.

S'il y a un fichier appelé pyvenv.cfgdans le même répertoire que sys.executableou un répertoire en haut, python l'examine. Différents systèmes d'exploitation font des choses différentes avec ce fichier.

L'une des valeurs de ce fichier de configuration que python recherche est l'option de configuration home = <DIRECTORY>. Python utilisera ce répertoire au lieu du répertoire contenant sys.executable lorsqu'il définit dynamiquement la valeur initiale de sys.prefixlater. Si le applocal = trueparamètre apparaît dans le pyvenv.cfgfichier sous Windows, mais pas le home = <DIRECTORY>paramètre, il sys.prefixsera défini sur le répertoire contenant sys.executable.

Ensuite, la PYTHONHOMEvariable d'environnement est examinée. Sous Linux et Mac, sys.prefixet sys.exec_prefixsont définis sur la PYTHONHOMEvariable d'environnement, si elle existe, remplaçant tout home = <DIRECTORY>paramètre dans pyvenv.cfg. Sous Windows, sys.prefixet sys.exec_prefixest défini sur la PYTHONHOMEvariable d'environnement, si elle existe, sauf si un home = <DIRECTORY>paramètre est présent dans pyvenv.cfg, qui est utilisé à la place.

Sinon, ceux sys.prefix- ci et sys.exec_prefixsont trouvés en marchant en arrière à partir de l'emplacement de sys.executable, ou du homerépertoire donné par le pyvenv.cfgcas échéant.

Si le fichier lib/python<version>/dyn-loadse trouve dans ce répertoire ou dans l'un de ses répertoires parents, ce répertoire est défini pour être sys.exec_prefixsur Linux ou Mac. Si le fichier lib/python<version>/os.pyse trouve dans le répertoire ou dans l'un de ses sous-répertoires, ce répertoire est défini pour être sys.prefixsous Linux, Mac et Windows, avec sys.exec_prefixla même valeur que sys.prefixsous Windows. Cette étape entière est ignorée sous Windows si elle applocal = trueest définie. Soit le répertoire de sys.executableest utilisé, soit, s'il homeest défini dans pyvenv.cfg, il est utilisé à la place pour la valeur initiale de sys.prefix.

S'il ne peut pas trouver ces fichiers "repères" ou sys.prefixn'a pas encore été trouvé, alors python définit sys.prefixune valeur de "repli". Linux et Mac, par exemple, utilisent des valeurs par défaut précompilées comme valeurs de sys.prefixet sys.exec_prefix. Windows attend que ce sys.pathsoit complètement compris pour définir une valeur de secours pour sys.prefix.

Ensuite, (ce que vous attendiez tous), python détermine les valeurs initiales qui doivent être contenues dans sys.path.

  1. Le répertoire du script exécuté par python est ajouté sys.path. Sous Windows, il s'agit toujours de la chaîne vide, qui indique à python d'utiliser le chemin complet où se trouve le script à la place.
  2. Le contenu de la variable d'environnement PYTHONPATH, s'il est défini, est ajouté à sys.path, sauf si vous êtes sous Windows et applocalest défini sur true dans pyvenv.cfg.
  3. Le chemin du fichier zip, qui se trouve <prefix>/lib/python35.zipsur Linux / Mac et os.path.join(os.dirname(sys.executable), "python.zip")Windows, est ajouté à sys.path.
  4. Si sous Windows et non a applocal = trueété défini pyvenv.cfg, le contenu des sous-clés de la clé de registre HK_CURRENT_USER\Software\Python\PythonCore\<DLLVersion>\PythonPath\est ajouté, le cas échéant.
  5. Si sous Windows et que no a applocal = trueété défini dans pyvenv.cfg, et sys.prefixn'a pas pu être trouvé, alors le contenu de base de la clé de registre HK_CURRENT_USER\Software\Python\PythonCore\<DLLVersion>\PythonPath\est ajouté, s'il existe;
  6. Si sous Windows et non a applocal = trueété défini pyvenv.cfg, le contenu des sous-clés de la clé de registre HK_LOCAL_MACHINE\Software\Python\PythonCore\<DLLVersion>\PythonPath\est ajouté, le cas échéant.
  7. Si sous Windows et que no a applocal = trueété défini dans pyvenv.cfg, et sys.prefixn'a pas pu être trouvé, alors le contenu de base de la clé de registre HK_CURRENT_USER\Software\Python\PythonCore\<DLLVersion>\PythonPath\est ajouté, s'il existe;
  8. Si sous Windows et que PYTHONPATH n'a pas été défini, le préfixe n'a pas été trouvé et qu'aucune clé de registre n'était présente, la valeur relative à la compilation de PYTHONPATH est ajoutée; sinon, cette étape est ignorée.
  9. Les chemins dans la macro PYTHONPATH au moment de la compilation sont ajoutés par rapport au fichier trouvé dynamiquement sys.prefix.
  10. Sur Mac et Linux, la valeur de sys.exec_prefixest ajoutée. Sous Windows, le répertoire qui a été utilisé (ou aurait été utilisé) pour rechercher dynamiquement sys.prefixest ajouté.

À ce stade sous Windows, si aucun préfixe n'a été trouvé, python essaiera de le déterminer en recherchant dans tous les répertoires sys.pathles fichiers de repère, comme il a essayé de le faire avec le répertoire de sys.executableprécédemment, jusqu'à ce qu'il trouve quelque chose. Si ce n'est pas le cas, sys.prefixest laissé vide.

Enfin, après tout cela, Python charge le sitemodule, ce qui ajoute encore plus de choses à sys.path:

Il commence par construire jusqu'à quatre répertoires à partir d'une partie de tête et d'une partie de queue. Pour la partie tête, il utilise sys.prefixet sys.exec_prefix; les têtes vides sont ignorées. Pour la partie queue, il utilise la chaîne vide puis lib/site-packages(sous Windows) ou lib/pythonX.Y/site-packages et puis lib/site-python(sous Unix et Macintosh). Pour chacune des combinaisons tête-queue distinctes, il voit s'il fait référence à un répertoire existant, et si c'est le cas, l'ajoute à sys.path et inspecte également le chemin nouvellement ajouté pour les fichiers de configuration.


1
Malgré ce que disent ses documents, il sys.executablepeut s'agir d'un lien symbolique ou en fait de n'importe quoi s'il argv[0]contient des barres obliques. Le chemin d' accès réel à l'exécutable (à partir de l' execv(path, argv)appel) n'est pas utilisé.
jfs

1
Concernant votre premier point pour sys.pathWindows 10: j'obtiens toujours le chemin complet de mon répertoire de script comme sys.path [0] (pas cwd ''). Vous devriez pouvoir exécuter quelque chose commepython some\other\path\than\cwd\main.py
ford04

Je suis d'accord avec @ ford04. Le point 1 est incorrect: sous Windows, le répertoire du script est ajouté à sys.path, pas à un chemin vide, ni à cwd. C'est dans diverses installations de Python 3.x.
gwideman

1
Wow, c'est génial! J'ai vu environ 10 autres questions et réponses avant de tomber sur ceci, la «vérité», même si vous admettez avec humilité que vous n'avez pas tout à fait tout.
Mike Williamson

1
J'ajouterais que les fichiers pertinents site-packagesont .pthet les .egg-linksuffixes.
florisla le
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.