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

Resuelto Alex asked hace 15 años • 2 respuestas

¿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 anteriores a los de PYTHONPATH.

Alex avatar May 22 '09 20:05 Alex
Aceptado

EDITAR

Cuando escribí esto en 2015, no había documentación sobre el tema. Ahora hay comentarios, si quieres comprobarlo también. También hay una explicación en prosa del algoritmo en los comentarios getpath.pydel código base. Sigo creyendo que mi respuesta es relevante y relativamente actual.

SIGUE EL TEXTO ORIGINAL

Python realmente se esfuerza por configurar de forma inteligente sys.path. La forma en que se configura puede resultar realmente complicada . La siguiente guía es una guía diluida, algo incompleta, algo incorrecta, pero con suerte útil para el programador común de Python sobre lo que sucede cuando Python descubre qué usar como valores iniciales de sys.path, sys.executable, sys.exec_prefixy sys.prefixen una instalación normal de Python.

En primer lugar, Python hace todo lo posible para determinar su ubicación física real en el sistema de archivos en función de lo que le indica el sistema operativo. Si el sistema operativo simplemente dice que "python" se está ejecutando, se encuentra en $PATH. Resuelve cualquier enlace simbólico. Una vez hecho esto, la ruta del ejecutable que encuentra se utiliza como valor para sys.executable, sin condiciones, ni peros.

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 examina. 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 establezca dinámicamente el valor inicial de sys.prefixmás tarde. 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.prefixse sys.exec_prefixconfiguran 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.executableo el homedirectorio proporcionado por, pyvenv.cfgsi corresponde.

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 sys.prefixen Linux, Mac y Windows, con sys.exec_prefixel mismo valor que sys.prefixen Windows. Todo este paso se omite en Windows si applocal = trueestá configurado. sys.executableSe utiliza el directorio de o, si homeestá configurado en pyvenv.cfg, se utiliza en lugar del valor inicial de sys.prefix.

Si no puede encontrar estos archivos "históricos" o sys.prefixaún no los ha encontrado, entonces Python establece sys.prefixun valor "alternativo". Linux y Mac, por ejemplo, utilizan valores predeterminados precompilados como valores de sys.prefixy sys.exec_prefix. Windows espera hasta que sys.pathesté completamente resuelto para establecer un valor alternativo para sys.prefix.

Luego, (lo que todos estaban esperando), Python determina los valores iniciales que estarán contenidos en sys.path.

  1. Se agrega el directorio del script que Python está ejecutando sys.path. En Windows, esta es siempre la cadena vacía, lo que le indica a Python que use la ruta completa donde se encuentra el script.
  2. El contenido de la variable de entorno PYTHONPATH, si está configurada, se agrega a sys.path, a menos que esté en Windows y applocalesté configurada como verdadera en pyvenv.cfg.
  3. La ruta del archivo zip, que se encuentra <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ó , se agrega pyvenv.cfgel contenido de las subclaves de la clave de registro , si corresponde.HK_CURRENT_USER\Software\Python\PythonCore\<DLLVersion>\PythonPath\
  5. Si en Windows 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ó , se agrega pyvenv.cfgel contenido de las subclaves de la clave de registro , si corresponde.HK_LOCAL_MACHINE\Software\Python\PythonCore\<DLLVersion>\PythonPath\
  7. Si en Windows 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 presentes, entonces se agrega el valor relativo en tiempo de compilación de PYTHONPATH; de lo contrario, este paso se ignora.
  9. Las rutas en la macro PYTHONPATH en tiempo de compilación se agregan en relación con el archivo sys.prefix.
  10. sys.exec_prefixEn Mac y Linux, se agrega el valor de . sys.prefixEn Windows, se 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 sys.executableanterior, 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 principal y otra final. Para la parte de la cabeza utiliza sys.prefixy sys.exec_prefix; Se omiten las cabezas vacías. Para la parte final, utiliza 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 hace referencia a un directorio existente y, de ser así, lo agrega a sys.path y también inspecciona la ruta recién agregada para buscar archivos de configuración.


EDITAR: No hay más getpathp.c(enlace al principio sobre palabra complicada ) desde diciembre de 2021 porque la implementación se transfirió a Python:getpath.py

djhaskin987 avatar Jul 15 '2016 19:07 djhaskin987

"Inicializado desde la variable de entorno PYTHONPATH, más un valor predeterminado que depende de la instalación"

-- http://docs.python.org/library/sys.html#sys.path

dfa avatar May 22 '2009 13:05 dfa