¿Desde dónde se inicializa sys.path de Python?


111

¿Desde dónde se inicializa sys.path de Python?

UPD : Python está agregando algunas rutas antes de hacer referencia 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']

Mi PYTHONPATH es:

    PYTHONPATH=c:\testdir

Me pregunto de dónde vienen esos caminos antes de los de PYTHONPATH.

Respuestas:



77

Python realmente se esfuerza por configurar inteligentemente sys.path. La forma en que se establece puede ser realmente complicada . La siguiente guía es un poco incompleto, guía aguada, un poco-mal, pero es de esperar-útil para la pitón programador rango y archivo de lo que sucede cuando las cifras del pitón lo usen como los valores iniciales de sys.path, sys.executable, sys.exec_prefix, y sys.prefixen una instalación normal de Python.

Primero, Python hace todo lo posible para averiguar su ubicación física real en el sistema de archivos basándose en lo que le dice el sistema operativo. Si el sistema operativo simplemente dice que "python" se está ejecutando, se encuentra en $ PATH. Resuelve los enlaces simbólicos. Una vez hecho esto, la ruta del ejecutable que encuentra se usa como el valor de sys.executable, no ifs, ands o buts.

A continuación, determina los valores iniciales de sys.exec_prefixy sys.prefix.

Si hay un archivo llamado pyvenv.cfgen el mismo directorio sys.executableo un directorio arriba, Python lo mira. Los diferentes sistemas operativos hacen cosas diferentes con este archivo.

Uno de los valores en este archivo de configuración que busca Python es la opción de configuración home = <DIRECTORY>. Python usará este directorio en lugar del directorio que contiene sys.executable cuando establece dinámicamente el valor inicial de sys.prefixlater. Si la applocal = trueconfiguración aparece en el pyvenv.cfgarchivo en Windows, pero no la home = <DIRECTORY>configuración, sys.prefixse establecerá en el directorio que contiene sys.executable.

A continuación, PYTHONHOMEse examina la variable de entorno. En Linux y Mac, sys.prefixy sys.exec_prefixse establecen en la PYTHONHOMEvariable de entorno, si existe, reemplazando cualquier home = <DIRECTORY>configuración en pyvenv.cfg. En Windows, sys.prefixy sys.exec_prefixse establece en la PYTHONHOMEvariable de entorno, si existe, a menos que haya una home = <DIRECTORY>configuración presente en pyvenv.cfg, que se usa en su lugar.

De lo contrario, estos sys.prefixy sys.exec_prefixse encuentran caminando hacia atrás desde la ubicación de sys.executable, o el homedirectorio dado por, pyvenv.cfgsi lo hubiera.

Si el archivo lib/python<version>/dyn-loadse encuentra en ese directorio o en cualquiera de sus directorios principales, ese directorio está configurado para estar sys.exec_prefixen Linux o Mac. Si el archivo lib/python<version>/os.pyse encuentra en el directorio o en cualquiera de sus subdirectorios, ese directorio está configurado para estar sys.prefixen Linux, Mac y Windows, con sys.exec_prefixel mismo valor que sys.prefixen Windows. Este paso completo se omite en Windows si applocal = trueestá configurado. Se sys.executableutiliza el directorio de o, si homese establece en pyvenv.cfg, se utiliza en su lugar para el valor inicial de sys.prefix.

Si no puede encontrar estos archivos "emblemáticos" o sys.prefixaún no los ha encontrado, entonces Python establece sys.prefixun valor de "respaldo". Linux y Mac, por ejemplo, usan valores predeterminados precompilados como valores de sys.prefixy sys.exec_prefix. Windows espera hasta que sys.pathesté completamente calculado para establecer un valor de respaldo sys.prefix.

Luego, (lo que todos han estado esperando), Python determina los valores iniciales que deben incluirse sys.path.

  1. Se agrega el directorio del script en el que se está ejecutando Python sys.path. En Windows, esta es siempre la cadena vacía, que le dice a Python que use la ruta completa donde se encuentra el script.
  2. El contenido de la variable de entorno PYTHONPATH, si se establece, se agrega a sys.path, a menos que esté en Windows y applocalesté establecido en verdadero en pyvenv.cfg.
  3. La ruta del archivo zip, que está <prefix>/lib/python35.zipen Linux / Mac y os.path.join(os.dirname(sys.executable), "python.zip")en Windows, se agrega a sys.path.
  4. Si en Windows y no applocal = truese configuró no pyvenv.cfg, entonces HK_CURRENT_USER\Software\Python\PythonCore\<DLLVersion>\PythonPath\se agrega el contenido de las subclaves de la clave de registro , si corresponde.
  5. Si en Windows y no applocal = truese configuró pyvenv.cfgy sys.prefixno se pudo encontrar, entonces se agrega el contenido principal de la clave de registro HK_CURRENT_USER\Software\Python\PythonCore\<DLLVersion>\PythonPath\, si existe;
  6. Si en Windows y no applocal = truese configuró no pyvenv.cfg, entonces HK_LOCAL_MACHINE\Software\Python\PythonCore\<DLLVersion>\PythonPath\se agrega el contenido de las subclaves de la clave de registro , si corresponde.
  7. Si en Windows y no applocal = truese configuró pyvenv.cfgy sys.prefixno se pudo encontrar, entonces se agrega el contenido principal de la clave de registro HK_CURRENT_USER\Software\Python\PythonCore\<DLLVersion>\PythonPath\, si existe;
  8. Si en Windows y no se configuró PYTHONPATH, no se encontró el prefijo y no había claves de registro, se agrega el valor relativo en tiempo de compilación de PYTHONPATH; de lo contrario, este paso se ignora.
  9. Las rutas de la macro en tiempo de compilación PYTHONPATH se agregan en relación con la que se encuentra dinámicamente sys.prefix.
  10. En Mac y Linux, sys.exec_prefixse agrega el valor de . En Windows, sys.prefixse agrega el directorio que se usó (o se habría usado) para buscar dinámicamente .

En esta etapa en Windows, si no se encontró ningún prefijo, Python intentará determinarlo buscando en todos los directorios sys.pathlos archivos de referencia, como intentó hacer con el directorio de sys.executableanteriormente, hasta que encuentre algo. Si no es así, sys.prefixse deja en blanco.

Finalmente, después de todo esto, Python carga el sitemódulo, que agrega cosas aún más a sys.path:

Comienza construyendo hasta cuatro directorios a partir de una parte inicial y otra final. Para la parte de la cabeza, usa sys.prefixy sys.exec_prefix; se saltan cabezas vacías. Para la parte final, usa la cadena vacía y luego lib/site-packages(en Windows) o lib/pythonX.Y/site-packages y luego lib/site-python(en Unix y Macintosh). Para cada una de las distintas combinaciones head-tail, ve si se refiere a un directorio existente y, si es así, lo agrega a sys.path y también inspecciona la ruta recién agregada para los archivos de configuración.


1
A pesar de lo que dicen sus documentos, sys.executablepuede ser un enlace simbólico o en realidad puede ser cualquier cosa si argv[0]contiene barras. No se utiliza la ruta real al ejecutable (desde la execv(path, argv)llamada).
jfs

1
Con respecto a su primer punto para sys.pathWindows 10: siempre obtengo la ruta completa de mi directorio de script como sys.path [0] (no cwd ''). Debería poder ejecutar algo comopython some\other\path\than\cwd\main.py
ford04

Estoy de acuerdo con @ ford04. El punto 1 es incorrecto: en Windows, el directorio de la secuencia de comandos se agrega a sys.path, no una ruta en blanco ni cwd. Esto se encuentra en varias instalaciones de Python 3.x.
gwideman

1
¡Vaya, esto es asombroso! Vi alrededor de otras 10 preguntas y respuestas antes de tropezar con esto, la "verdad", a pesar de que te sientes humilde al admitir que no lo tienes todo.
Mike Williamson

1
Agregaría que los archivos relevantes en site-packageshave .pthy .egg-linksufijos.
Florisla
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.