2012-07-30 16 views
17

imaginar la estructura de directorios:¿No deberían las importaciones ser absolutas por defecto en python27?

 
/
    a/ 
     __init__.py 
     b.py 
     c.py 
    c.py 

Archivo /a/b.py parece:

 
import c 
should_be_absolute = c 

Todos los demás archivos (incluyendo __init__) están vacías.

Cuando se ejecuta un script de prueba (utilizando Python 2.7):

import a.b 
print a.b.should_be_absolute 

con PYTHONPATH=/ de un directorio vacío (por lo que nada se añade a PYTHONPATH del directorio actual) consigo

<module 'a.c' from '/a/c.py'> 

donde según a PEP 328 y la declaración import <> is always absolute esperaría:

<module 'c' from '/c.py'> 

La salida es la esperada cuando elimino el archivo /a/c.py.

¿Qué me estoy perdiendo? Y si este es el comportamiento correcto, ¿cómo importar el módulo c desde b (en lugar de a.c)?

Actualización:

Según python dev mailing list que parece que hay un error en la documentación. Las importaciones son no absoluto por defecto en python27.

+0

¿Cuál es su ruta de acceso completa? ¿Es solo /? Probablemente debería estar usando un nombre de paquete raíz – jdi

+3

FWIW, esto funciona como espera en Python 3. – geoffspear

+0

@jdi - sí, la raíz es lo único en PYTHONPATH (editó la publicación original para hacerlo más explícito) – karolx

Respuesta

26

es necesario agregar from __future__ import absolute_import o utilizar importlib.import_module('c') en Python 2.7

Es predeterminada en Python 3.

Hubo un error en Python: __future__.py and its documentation claim absolute imports became mandatory in 2.7, but they didn't.

+2

¡Tienes razón! Después de seguir excavando encontré el enlace a la [lista de correo de python-dev] (http://python.6.n6.nabble.com/status-of-absolute-import-w-python-2-7-td1850742.html) confirmando que la característica absolute_import no está activada por defecto en python27. – karolx

+0

tipo de ridículo ... –

0

Si solo está agregando / a su PYTHONPATH, la orden de búsqueda aún podría estar buscando c en el directorio actual. Sería mucho mejor si colocó todo bajo un paquete raíz, y se refirió a ella en absoluto:

/myPackage 
    a/ 
     __init__.py 
     b.py 
     c.py 
    __init__.py 
    c.py 

Y un PYTHONPATH como: export PYTHONPATH=/:$PYTHONPATH

Así que en su a.c que haría y de éstos:

from myPackage import c 
from myPackage.c import Foo 
import myPackage.c 

De esta manera, siempre es relativo a su paquete.

+0

Gracias pero el la pregunta es más, ¿es esto un comportamiento correcto en lugar de cómo reorganizar el código para que funcione? El problema real que estoy resolviendo es que la 'c' es el nombre del módulo incorporado Python y el código del paquete en el que estoy trabajando está sombreándolo (y de acuerdo con los documentos python no debería) – karolx

-1

"Absoluto" no significa el que crees que hace; en su lugar, significa que el procedimiento de resolución del paquete "habitual" tiene lugar: primero, se ve en el directorio del paquete, luego en todos los elementos de sys.path; que incluye los elementos de PYTHONPATH.

Si realmente quiere, puede utilizar herramientas como el módulo imp, pero yo recomendaría que no lo haga por algo como esto. Porque en general, nunca debería tener que crear un módulo con el mismo nombre que uno en la distribución estándar de Python.

+0

Gracias @Ivo pero el [PEP 328 # rationale-for-absolute-imports] (http://www.python.org/dev/peps/pep-0328/#rationale-for-absolute-imports) establece que la importación absoluta _siempre será un módulo o paquete accesible desde sys.path_. No hay nada sobre la búsqueda en el directorio del paquete primero. ¿Puedes señalar algún recurso que documente el comportamiento que describiste por favor? – karolx

+0

http://docs.python.org/reference/simple_stmts.html#import es muy claro en el proceso a medida que se implementa: "Si se supone que el módulo que se está importando está contenido dentro de un paquete, entonces el segundo argumento pasó a find_module(), __path__ en el paquete principal, se utiliza como origen de las rutas ". – Ivo

+0

"primero, se ve en el directorio del paquete". No, eso es una importación relativa. –

Cuestiones relacionadas