from - python modules list
Python: la mejor manera de agregar a sys.path relativo al script en ejecuciĆ³n actual (6)
Tengo un directorio lleno de scripts (digamos project/bin
). También tengo una biblioteca ubicada en project/lib
y quiero que los scripts carguen automáticamente. Esto es lo que normalmente uso en la parte superior de cada script:
#!/usr/bin/python
from os.path import dirname, realpath, sep, pardir
import sys
sys.path.append(dirname(realpath(__file__)) + sep + pardir + sep + "lib")
# ... now the real code
import mylib
Esto es algo engorroso, feo y debe pegarse al comienzo de cada archivo. ¿Hay una mejor manera de hacer esto?
Realmente lo que estoy esperando es algo tan sencillo como esto:
#!/usr/bin/python
import sys.path
from os.path import pardir, sep
sys.path.append_relative(pardir + sep + "lib")
import mylib
O mejor aún, algo que no se rompería cuando mi editor (u otra persona que tenga acceso de confirmación) decida reordenar las importaciones como parte de su proceso de limpieza:
#!/usr/bin/python --relpath_append ../lib
import mylib
Eso no se transferiría directamente a plataformas que no sean posix, pero mantendría las cosas limpias.
Cree un project/bin/lib
módulo envoltorio project/bin/lib
, que contenga esto:
import sys, os
sys.path.insert(0, os.path.join(
os.path.dirname(os.path.dirname(os.path.realpath(__file__))), ''lib''))
import mylib
del sys.path[0], sys, os
Luego puede reemplazar todo el cruft en la parte superior de sus scripts con:
#!/usr/bin/python
from lib import mylib
Esto es lo que uso:
import os, sys
sys.path.append(os.path.join(os.path.dirname(__file__), "lib"))
Estoy usando:
import sys,os
sys.path.append(os.getcwd())
Hay un problema con cada respuesta proporcionada que se puede resumir como "simplemente agregue este conjuro mágico al comienzo de su secuencia de comandos. Vea lo que puede hacer con solo una o dos líneas de código". ¡No funcionarán en todas las situaciones posibles!
Por ejemplo, uno de estos conjuros mágicos usa el archivo . Desafortunadamente, si empaqueta su script usando cx_Freeze o está usando IDLE, esto dará como resultado una excepción.
Otro encantamiento mágico de este tipo usa os.getcwd (). Esto solo funcionará si está ejecutando el script desde el símbolo del sistema y el directorio que contiene el script es el directorio de trabajo actual (es decir, utilizó el comando cd para cambiar al directorio antes de ejecutar el script). Eh dioses! Espero no tener que explicar por qué esto no funcionará si su script de Python está en el PATH en alguna parte y lo ejecutó simplemente escribiendo el nombre de su archivo de script.
Afortunadamente, hay un conjuro mágico que funcionará en todos los casos que he probado. Desafortunadamente, el conjuro mágico es más que solo una o dos líneas de código.
import inspect
import os
import sys
# Add script directory to sys.path.
# This is complicated due to the fact that __file__ is not always defined.
def GetScriptDirectory():
if hasattr(GetScriptDirectory, "dir"):
return GetScriptDirectory.dir
module_path = ""
try:
# The easy way. Just use __file__.
# Unfortunately, __file__ is not available when cx_freeze is used or in IDLE.
module_path = __file__
except NameError:
if len(sys.argv) > 0 and len(sys.argv[0]) > 0 and os.path.isabs(sys.argv[0]):
module_path = sys.argv[0]
else:
module_path = os.path.abspath(inspect.getfile(GetScriptDirectory))
if not os.path.exists(module_path):
# If cx_freeze is used the value of the module_path variable at this point is in the following format.
# {PathToExeFile}/{NameOfPythonSourceFile}. This makes it necessary to strip off the file name to get the correct
# path.
module_path = os.path.dirname(module_path)
GetScriptDirectory.dir = os.path.dirname(module_path)
return GetScriptDirectory.dir
sys.path.append(os.path.join(GetScriptDirectory(), "lib"))
print(GetScriptDirectory())
print(sys.path)
Como puede ver, ¡esta no es una tarea fácil!
Si no desea cambiar el contenido del script de ninguna manera, anteponga el directorio de trabajo actual .
a $ PYTHONPATH (ver el ejemplo a continuación)
PYTHONPATH=.:$PYTHONPATH alembic revision --autogenerate -m "First revision"
¡Y llámalo un día!
Si no quieres editar cada archivo
- Instale su biblioteca como una libra de python normal
o - Establezca
PYTHONPATH
en sulib
o si está dispuesto a agregar una sola línea a cada archivo, agregue una declaración de importación en la parte superior, por ejemplo
import import_my_lib
mantenga import_my_lib.py
en bin e import_my_lib
pueda establecer correctamente la ruta de python a la lib
que desee