2009-06-25 12 views
28

Tengo un script de Python que usa módulos incorporados pero también importa una cantidad de módulos personalizados que existen en el mismo directorio que el script principal.Importación de módulos de Python desde diferentes directorios de trabajo

Por ejemplo, yo llamaría

python agent.py 

y agent.py tiene una serie de importaciones, incluyendo:

import checks 

donde los controles se encuentra en un archivo en el mismo directorio que agent.py

agent/agent.py 
agent/checks.py 

Cuando el directorio actual de trabajo es agent/then todo está bien. Sin embargo, si llamo a agent.py desde cualquier otro directorio, obviamente no puede importar checks.py y otros errores.

¿Cómo puedo asegurarme de que los módulos personalizados se puedan importar independientemente de dónde se llame a agent.py, p. Ej.

python /home/bob/scripts/agent/agent.py 
+0

Y el resultado fue ¿qué? ¿Estás planeando aceptar una respuesta? –

+0

Aceptaré una respuesta una vez que haya probado el código, lo cual no haré por unas semanas. No veo ninguna prisa en particular. – DavidM

+0

¿Qué código probó? Como he tratado de señalar con un ejemplo, y como uno o dos otros también han mencionado, lo que dices que hiciste debería funcionar y está documentado que solo funciona. En lugar de "intentar el código", díganos [como he sugerido] la información elemental que debería haber sido incluida con su pregunta (plataforma, versión de Python, rastreo completo y mensaje de error) además de la depuración elemental que sugerí ... unos minutos de tu tiempo; seis personas "corrieron" para darte una respuesta. –

Respuesta

26

En realidad el ejemplo funciona porque checks.py está en el mismo directorio que agent.py, pero dicen checks.py fue en el directorio precedente, por ejemplo;

agent/agent.py 
checks.py 

entonces se podría hacer lo siguiente:

path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) 
if not path in sys.path: 
    sys.path.insert(1, path) 
del path 

Nota el uso de __file__.

+0

¿Qué hay que tener en cuenta sobre del camino? ¿Por qué es eso especial? –

+0

@CharlieParker está en su lugar para limpiar la variable 'ruta '. Si quieres dejarlo dando vueltas, está bien. –

+2

+1 pero para principiantes python como yo, no olvides agregar 'import os, sys' (sin la cita) para que esto funcione bien :) – icasimpan

6

Debe agregar la ruta del módulo que se está ejecutando actualmente a la variable sys.path. Como lo llamó en la línea de comandos, la ruta de acceso al script siempre estará en sys.argv [0].

import sys 
import os 
sys.path.append(os.path.split(sys.argv[0])[0]) 

Ahora cuando la importación busca el módulo, también buscará en la carpeta que aloja el archivo agent.py.

5

Hay varias formas de agregar cosas al PYTHONPATH.

Leer http://docs.python.org/library/site.html

  1. Establecer la variable de entorno PYTHONPATH antes de ejecutar la secuencia de comandos.

    Puede hacer esto python -m agent para ejecutar agent.py desde su PYTHONPATH.

  2. Cree .pth archivos en su directorio lib/site-packages.

  3. Instale sus módulos en lib/site-packages.

11

NO deberías tener que jugar con sys.path. Para citar de Python 2.6 documentos para sys.ruta:

Como se ha inicializado en el inicio del programa, el primer elemento de esta lista, camino [0], es el directorio que contiene la secuencia de comandos que se utilizó para invocar el intérprete de Python. Si el directorio de scripts no está disponible (por ejemplo, si el intérprete se invoca interactivamente o si el script se lee de la entrada estándar), la ruta [0] es la cadena vacía que dirige Python para buscar módulos en el directorio actual primero. Observe que el directorio de scripts se inserta antes de las entradas insertadas como resultado de PYTHONPATH.

=== amod.py === 
def whoami(): 
    return __file__ 

=== ascript.py === 
import sys 
print "sys.argv", sys.argv 
print "sys.path", sys.path 
import amod 
print "amod __file__", amod.whoami() 

=== result of running ascript.py from afar === 
C:\somewhere_else>\python26\python \junk\timport\ascript.py 
sys.argv ['\\junk\\timport\\ascript.py'] 
sys.path ['C:\\junk\\timport', 'C:\\WINDOWS\\system32\\python26.zip', SNIP] 
amod __file__ C:\junk\timport\amod.py 

y si se vuelve a ejecutar, los últimos cambios en la formación, por supuesto, a ... amod.pyc. Esto parece no ser una novedad, funciona con Python 2.1 y 1.5.2.

Sugerencias de depuración: Pruebe dos archivos simples como los que tengo. Intenta ejecutar Python con -v y -vv. Muéstranos los resultados de tus pruebas fallidas, incluido el rastreo completo y el mensaje de error, y tus dos archivos. Cuéntanos en qué plataforma estás ejecutando y qué versión de Python. Compruebe los permisos en el archivo checks.py. ¿Hay un checks.something_else que esté causando interferencia?

+0

Siento que esta debería ser la respuesta correcta ... El OP habla claramente de invocar en lugar de importar script (s) desde diferentes ubicaciones. –

1

Creo que deberías considerar hacer el directorio del agente en un paquete apropiado de Python. A continuación, se coloca este paquete en cualquier parte de la ruta de pitón, y puede importar los cheques como

from agent import checks 

Ver http://docs.python.org/tutorial/modules.html

1

Si conoces ruta completa a check.py uso esta receta (http://code.activestate.com/recipes/159571/)

Si desea agregar el directorio a la ruta del sistema: esta receta (http://code.activestate.com/recipes/52662/). En este caso, debo determinar el directorio de la aplicación (sys.argv [0]) y pasar este valor a la función AddSysPath. Si quieres ver la muestra de producción, por favor deja un comentario sobre este hilo así que lo publico más tarde.

Atentamente.

0

Para generalizar mi comprensión de su objetivo, desea poder importar paquetes personalizados utilizando import custom_package_name sin importar desde dónde llame python y sin importar dónde se encuentra su secuencia de comandos python.

Una serie de respuestas mencionan lo que voy a describir, pero creo que la mayoría de las respuestas asumen muchos conocimientos previos. Trataré de ser tan explícito como pueda.

Para lograr el objetivo de permitir que los paquetes personalizados se importen a través de la declaración import, tienen que ser detectables en algún lugar a través de la ruta que utiliza python para buscar paquetes. Python en realidad usa múltiples rutas, pero solo nos enfocaremos en la que se puede encontrar combinando la salida de sys.prefix (en su intérprete de python) con /lib/pythonX.Y/site-packages (o lib/site-packages si está usando Windows) donde X.Y es su versión de python.

Concretamente, encontrar el camino que utiliza su pitón ejecutando:

import sys 
your_path = sys.prefix + '/lib/pythonX.Y/site-packages' 
print(your_path) 

Este camino debe ser algo como /usr/local/lib/python3.5/site-packages si estás usando Python 3.5, pero podría ser muy diferente dependiendo de su configuración.

Python usa esta ruta (y algunas otras) para encontrar los paquetes que desea importar. Entonces, lo que puede hacer es colocar sus paquetes personalizados en la carpeta /usr/local/lib/python3.5/site-packages. No olvide agregar un archivo init .py a la carpeta.

Para ser concretos de nuevo, en el tipo de terminal:

cd your_path 
cp path_to_custom_package/custom_package ./ 

Ahora usted debería ser capaz de importar todo el paquete personalizado como lo haría si el paquete estaba situada en el mismo directorio (es decir import package.subpackage para cada archivo subpaquete en tu paquete debería funcionar).

+0

Algunas preguntas son intemporales –

Cuestiones relacionadas