2010-06-29 19 views
55

Acabo de unirme a un proyecto con una base de código existente bastante grande. Desarrollamos en linux y no usamos e IDE. Corremos a través de la línea de comando. Estoy intentando descubrir cómo conseguir que python busque la ruta correcta cuando ejecuto los módulos del proyecto. Por ejemplo, cuando corro algo como:Expandir Ruta de búsqueda de Python a otra fuente

python someprojectfile.py 

consigo

ImportError: no module named core.'somemodule' 

consigo esto para todos mis importaciones a supongo que es un problema con la ruta de acceso.

TLDR:

¿Cómo llego a la lista de Python ~/codez/project/ y todos los archivos y carpetas para archivos * .py durante las declaraciones de importación.

Respuesta

95

Hay algunas maneras posibles de hacer esto:

  • Establecer la variable de entorno PYTHONPATH a una lista separada por comas de los directorios para buscar los módulos importados.
  • En su programa, use sys.path.append('/path/to/search') para agregar los nombres de los directorios que desea que Python busque módulos importados. sys.path es solo la lista de directorios que Python busca cada vez que se le pide que importe un módulo, y puede modificarlo según sea necesario (¡aunque yo no recomendaría eliminar ninguno de los directorios estándar!). Cualquier directorio que coloque en la variable de entorno PYTHONPATH se insertará en sys.path cuando se inicie Python.
  • Utilice site.addsitedir para agregar un directorio a sys.path. La diferencia entre esto y simplemente anexa es que cuando usa addsitedir, también busca los archivos .pth dentro de ese directorio y los usa para posiblemente agregar directorios adicionales a sys.path según el contenido de los archivos. Vea la documentación para más detalles.

Cuál de estos desea utilizar depende de su situación. Recuerde que cuando distribuye su proyecto a otros usuarios, generalmente lo instalan de tal manera que los archivos de código de Python serán detectados automáticamente por el importador de Python (es decir, los paquetes generalmente se instalan en el directorio site-packages), así que si se entromete con sys.path en su código, que puede ser innecesario e incluso puede tener efectos adversos cuando ese código se ejecuta en otra computadora. Para el desarrollo, me atrevería a suponer que establecer PYTHONPATH suele ser la mejor opción.

Sin embargo, cuando se está usando algo que sólo se ejecuta en su propio ordenador (o cuando se tiene configuraciones no estándar, por ejemplo, a veces en los marcos de aplicaciones web), no es del todo infrecuente que hacer algo como

from os.path import dirname 
sys.path.append(dirname(__file__)) 
+0

Así que si tuviera 15 subdirectorios, ¿tendría que agregarlos individualmente? – themaestro

+0

y podría dar un ejemplo de un argumento de línea de comando para cambiar PYTHONPATH? – themaestro

+2

Para establecer 'PYTHONPATH': en' .bashrc' o en cualquier archivo de inicio que utilice su shell (si no es Bash), escriba 'export PYTHONPATH = $ PYTHONPATH: $ HOME/codez/project'. Pero si tienes un montón de subdirectorios, crearía un archivo '.pth' y usar' site.addsitedir'. Puede crear un módulo 'sitecustomize' que pueda llamar a la función por usted; intente ponerlo en '~/.local/lib/python2.6/sitecustomize.py' (sustituya su versión de Python) por lo que con suerte se importará automáticamente. –

9

También debería leer sobre los paquetes de Python aquí: http://docs.python.org/tutorial/modules.html.

Según su ejemplo, supongo que realmente tiene un paquete en ~/codez/project. El archivo __init__.py en un directorio python mapea un directorio en un espacio de nombres. Si todos sus subdirectorios tienen un archivo __init__.py, solo necesita agregar el directorio base a su PYTHONPATH.Por ejemplo:

PYTHONPATH = $ PYTHONPATH: $ HOME/adaifotis/proyecto

Además de probar la variable de entorno PYTHONPATH, como explica David, puede probarlo en Python como esto:

$ python 
>>> import project      # should work if PYTHONPATH set 
>>> import sys 
>>> for line in sys.path: print line # print current python path 

...

+0

Puede poner su '__init __. Py' en palos de atrás para dejar en claro que realmente quiere decir' __init __. Py', en oposición a 'init.py'. Solo para evitar confundir a los novatos. :) – antred

2

leí esta pregunta en busca de una respuesta, y no le gustaba ninguno de ellos.

Así que escribí una solución rápida y sucia. Sólo hay que poner esto en alguna parte en su sys.path, y va a añadir cualquier directorio bajo folder (desde el directorio de trabajo actual), o bajo abspath:

#using.py 

import sys, os.path 

def all_from(folder='', abspath=None): 
    """add all dirs under `folder` to sys.path if any .py files are found. 
    Use an abspath if you'd rather do it that way. 

    Uses the current working directory as the location of using.py. 
    Keep in mind that os.walk goes *all the way* down the directory tree. 
    With that, try not to use this on something too close to '/' 

    """ 
    add = set(sys.path) 
    if abspath is None: 
     cwd = os.path.abspath(os.path.curdir) 
     abspath = os.path.join(cwd, folder) 
    for root, dirs, files in os.walk(abspath): 
     for f in files: 
      if f[-3:] in '.py': 
       add.add(root) 
       break 
    for i in add: sys.path.append(i) 

>>> import using, sys, pprint 
>>> using.all_from('py') #if in ~, /home/user/py/ 
>>> pprint.pprint(sys.path) 
[ 
#that was easy 
] 

Y me gusta porque puede tener una carpeta para algunos herramientas aleatorias y no hacer que formen parte de paquetes ni nada, y aún así tener acceso a algunas (o todas) en un par de líneas de código.

1

La manera más fácil que encuentro es crear un archivo "any_name.pth" y ponerlo en su carpeta "\ Lib \ site-packages". Deberías encontrar esa carpeta dondequiera que esté instalado Python.

En ese archivo, coloque una lista de directorios donde desea mantener los módulos para importar. Por ejemplo, hacer una línea en el archivo de esta manera:

C: \ Users \ ejemplo ... \ ejemplo

usted será capaz de decir que funciona mediante la ejecución de este en Python:

import sys 
for line in sys: print line 

Verá su directorio impreso, entre otros desde donde también puede importar. Ahora se puede importar un archivo "mymodule.py" que se encuentra en ese directorio con tanta facilidad como:

import mymodule 

Esto no va a importar subcarpetas. Para eso, podría imaginarse la creación de un script python para crear un archivo .pth que contenga todas las subcarpetas de una carpeta que usted defina. Hazlo funcionar en el arranque tal vez.

1

Sé que este hilo es un poco viejo, pero me llevó algo de tiempo llegar al corazón de esto, así que quería compartirlo.

En mi proyecto, tenía la secuencia de comandos principal en un directorio principal y, para diferenciar los módulos, puse todos los módulos de soporte en una subcarpeta llamada "módulos". En mi script principal, puedo importar estos módulos de este tipo (por un módulo llamado report.py):

de modules.report informe de importación, ReportError

Si llamo a mi script principal, esto funciona. Sin embargo, quería probar cada módulo mediante la inclusión de un main() en cada uno, y llamando a cada uno directamente, como: módulos

pitón \ report.py

Ahora Python se queja de que no puede encontrar "un módulo módulos llamados ". La clave aquí es que, de manera predeterminada, Python incluye la carpeta del script en su ruta de búsqueda, PERO NO EL CWD. Entonces, lo que este error dice, en realidad, es "No puedo encontrar una subcarpeta de módulos".Esto se debe a que no existe un subdirectorio "modules" del directorio donde reside el módulo report.py.

me parece que la solución más elegante a este es anexar la caquexia crónica en la ruta de búsqueda de Python mediante la inclusión de este en la parte superior: ("")

import sys

sys.path.append

Ahora Python busca en el CWD (directorio actual), encuentra la subcarpeta "modules" y todo está bien.

Cuestiones relacionadas