2012-01-21 12 views
51

¿Cómo importo un módulo (archivo python) que reside en el directorio principal?Importar secuencia de comandos desde un directorio primario

Ambos directorios tienen un archivo __init__.py pero todavía no puedo importar un archivo desde el directorio principal?

En este diseño de carpeta, Guión B está tratando de importar secuencias de comandos A:

Folder A: 
    __init__.py 
    Script A: 
    Folder B: 
    __init__.py 
    Script B(attempting to import Script A) 

El siguiente código en Script B no funciona:

import ../scriptA.py # I get a compile error saying the "." is invalid 
+0

No exactamente respondiendo su pregunta, pero si ejecuta __init__.py dentro de la Carpeta A y prueba e importa la Carpeta B o la Escritura B, la Secuencia de comandos A se importará correctamente dentro de la Secuencia de comandos B. – Michael0x2a

Respuesta

52

no realiza la importación de scripts en Python que importe módulos. Algunos módulos de python también son scripts que puede ejecutar directamente (hacen un trabajo útil a nivel de módulo).

En general, es preferible utilizar importaciones absolutas en lugar de importaciones relativas.

toplevel_package/ 
├── __init__.py 
├── moduleA.py 
└── subpackage 
    ├── __init__.py 
    └── moduleB.py 

En moduleB:

from toplevel_package import moduleA 

Si desea ejecutar moduleB.py como un script a continuación, asegúrese de que el directorio padre para toplevel_package está en su sys.path.

+5

¿Y por qué no se deberían usar los "hacks" de sys path en este caso? Python hace que sea tan difícil hacer lo que quieras aquí sin ellos. ¿Cuál es exactamente la desventaja aquí? –

+2

@BT * «' sys.path.append (path_to_parent) '» * no debería ser una respuesta a cómo arreglar * «" import ../scriptA.py # Recibo un error de compilación que dice que "." No es válido "» * Pregunta. Hay casos en los que cambiar 'sys.path' podría ser útil, p., si Python lo había hecho o un módulo de 3 partes que maneja todos los casos de esquina correctamente, por ejemplo, 'importación autopath; autopath.add_toplevel_to_syspath() 'que agrega automáticamente el directorio padre de toplevel_package a' sys.path' para permitir la ejecución directa del módulo interno como un script (o en un REPL) desde cualquier directorio sin la instalación apropiada de PYTHONPATH o (virtualenv). – jfs

+0

@JFSebastian ¿Hay alguna clase de propuesta para una característica que nos permita decir explícitamente cuál es la carpeta principal o el paquete de todo el proyecto para que no tengamos que preocuparnos de agregar directorios padre a 'sys.path' para que que podemos ejecutar los submódulos también como archivos principales o scripts? Tengo un proyecto en el que realmente necesito ejecutar scripts tanto como main como como módulos, eso es importado, pero necesito hacer toneladas de hacks añadiendo rutas a 'sys.path' para que funcionen en ambos casos. ¿Funcionaría de alguna manera en virtualenv o usar setuptools? Realmente estoy luchando con esto ... – nbro

24

Desde el docs:

from .. import scriptA 

Puede hacerlo en paquetes, pero no en scripts que ejecuta directamente. Desde el enlace de arriba:

Note that both explicit and implicit relative imports are based on the name of the current module. Since the name of the main module is always "__main__", modules intended for use as the main module of a Python application should always use absolute imports.

Si crea un script que importa A.B.B, usted no recibirá la ValueError.

+15

ValueError: Intento de importación relativa en el paquete – jgritty

+3

@jgritty, eso es porque lo estás haciendo en un script que estás ejecutando directamente. –

+2

Sí, tienes razón. Funcionará si llama un script que luego importa el Script B. – jgritty

4

Si desea ejecutar el script directamente, puede:

  1. Añadir la trayectoria de la FolderA a la variable de entorno (PYTHONPATH).
  2. Agregue la ruta a sys.path en su secuencia de comandos.

continuación:

import module_you_wanted 
Cuestiones relacionadas