script para paquetes modulos lista librerias instalar importar descargar clases bibliotecas python import environment-variables sys

para - lista de modulos de python



Establezca LD_LIBRARY_PATH antes de importar en Python (3)

Python utiliza la variable de entorno PYTHONPATH para determinar en qué carpetas debe buscar los módulos. Puedes jugar con él modificando sys.path , que funciona bien para los módulos Python puros. Pero cuando un módulo utiliza archivos de objetos compartidos o bibliotecas estáticas, busca aquellos en LD_LIBRARY_PATH (en linux), pero esto no se puede cambiar tan fácilmente y depende de la plataforma, que yo sepa.

La solución rápida para este problema es, por supuesto, establecer la variable de entorno o invocar el script como LD_LIBRARY_PATH=. ./script.py LD_LIBRARY_PATH=. ./script.py , pero luego tendrá que configurarlo de nuevo para cada nuevo shell que abra. Además, los archivos .so en mi caso siempre estarán en el mismo directorio que el archivo .py , pero se pueden mover a otra ruta absoluta, así que me gustaría configurarlos automáticamente cada vez que invoco el script.

¿Cómo puedo editar la ruta en la que el intérprete de Python busca las bibliotecas de forma independiente en tiempo de ejecución?

EDITAR:

Ya probé os.environ[''LD_LIBRARY_PATH''] = os.getcwd() , pero fue en vano.


Mi solución a este problema es poner esto como la primera línea de un script de Python (en lugar del shebang habitual):

exec env LD_LIBRARY_PATH=/some/path/to/lib /path/to/specific/python -x "$0" "$@"

Y aquí es cómo funciona esto:

  • sin shebang el shell actual trata el archivo como un script de shell,
  • "exec" asegura que esta primera línea es también el último comando de este archivo ejecutado por el shell,
  • "env" se utiliza aquí para establecer cualquier variable de entorno, por ejemplo, LD_LIBRARY_PATH,
  • se puede especificar una ruta exacta al intérprete de Python o "env" puede encontrar uno en PATH,
  • "-x" es una opción de Python que hace que el intérprete de Python ignore la primera línea,
  • "$ 0" es el nombre del script, "$ @" se sustituye por parámetros posicionales.

Python, cuando obtiene los valores de las variables de entorno como os.environ[''LD_LIBRARY_PATH''] o os.environ[''PATH''] , copia los valores, en un diccionario, desde el entorno del proceso principal, generalmente bash (entorno del proceso bash get se lleva al proceso hijo, la instancia en ejecución de python).

Puede ver esta sección de variable de entorno con el comando env salida de bash.

También puede ver / leer estos datos env desde /proc/<pid>/environ , introduciendo un bucle infinito ( while 1: pass ) después de modificar cualquier variable de entorno.

Si ve / lee este valor de variable / data desde /proc/<pid>/environ después de modificarlo dentro del script de python, vería que los datos de la variable real no se modifican, aunque el script de python muestra una modificación valor clave del diccionario, actualizado.

Lo que realmente sucede cuando modifica una variable env dentro de la secuencia de comandos python, como en os.environ[''LD_LIBRARY_PATH'']=''/<new_location>'' , es que simplemente actualiza el valor en el diccionario local, que no está asignado a la variable env del proceso sección. Por lo tanto, no se propagará completamente para reflejarse en el entorno del proceso actual, ya que SOLAMENTE se modificó / actualizó / completó un diccionario local .

Por lo tanto, si queremos que la nueva variable de entorno se refleje, deberíamos sobrescribir la imagen de memoria del proceso con nuevos datos de la variable de entorno, utilizando execv .

Ejemplo:

new_lib = ''/<new_location>'' if not new_lib in os.environ[''LD_LIBRARY_PATH'']: os.environ[''LD_LIBRARY_PATH''] += '':''+new_lib try: os.execv(sys.argv[0], sys.argv) except Exception as e: sys.exit(''EXCEPTION: Failed to Execute under modified environment, ''+e) import xyz #do something else

Limitación : Idealmente, python no debería permitir tal modificación de os.environ variables os.environ . Pero como no existe un tipo de datos de diccionario constante, permite la modificación de la variable de datos. No es absolutamente necesario modificar los valores, ya que no hace nada útil para reflejar en el entorno real del proceso en ejecución, a menos que se utilice execv .


Yo usaría:

import os os.environ[''LD_LIBRARY_PATH''] = os.getcwd() # or whatever path you want

Esto establece la LD_LIBRARY_PATH entorno LD_LIBRARY_PATH para la duración / duración de la ejecución del proceso actual.

EDIT: parece que esto debe configurarse antes de iniciar Python: Cambiar LD_LIBRARY_PATH en tiempo de ejecución para ctypes

Así que sugiero ir con un script .sh (o .py si insistes). Además, como señaló @chepner, es posible que desee considerar la instalación de sus archivos .so en una ubicación estándar (dentro del virtualenv).

Consulte también Configuración LD_LIBRARY_PATH desde dentro de Python