2011-07-18 8 views
7

asumir la estructura siguiente código:¿Por qué estas dos importaciones de Python funcionan de manera diferente?

#### 1/hhh/__init__.py: empty 

#### 1/hhh/foo/__init__.py: 
from hhh.foo.baz import * 

#### 1/hhh/foo/bar.py: 
xyzzy = 4 

#### 1/hhh/foo/baz.py: 
import hhh.foo.bar as bar 
qux = bar.xyzzy + 10 

corro python dentro 1/ y hacer import hhh.foo.baz. Se produce un error:

Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "hhh/foo/__init__.py", line 1, in <module> 
    from hhh.foo.baz import * 
    File "hhh/foo/baz.py", line 1, in <module> 
    import hhh.foo.bar as bar 
AttributeError: 'module' object has no attribute 'foo' 

Ahora puedo reemplazar con baz.py:

# 1/hhh/foo/baz.py: 
from hhh.foo.bar import xyzzy 
qux = xyzzy + 10 

y otra vez lo hacen import hhh.foo.baz. Ahora funciona, aunque estoy cargando el mismo módulo, solo vinculando un nombre diferente.

¿Esto significa que la distinción entre import module y from module import name va más allá de los identificadores? Qué está pasando aquí?

(Sé que puedo utilizar las importaciones en relación a evitar todo esto, pero aún así me gustaría entender la mecánica. Además de que no les gustan las importaciones en relación, y tampoco lo hace PEP 8.)

Respuesta

8

Cuando escribe from hhh.foo.bar import xyzzy El intérprete de Python intentará cargar xyzzy desde el módulo hhh.foo.bar. Pero si escribe import hhh.foo.bar as bar, primero intentará encontrar bar en el módulo hhh.foo. Por lo tanto, evalúa hhh.foo, haciendo from hhh.foo.baz import * . hhh.foo.baz intenta evaluar hhh.foo, hhh.foo intenta evaluar hhh.foo.baz, importaciones cíclicas, excepción.

+0

Bien, entonces existe la diferencia en semántica. ¡Gracias! –

0

en 1/hhh/foo/__init__.py necesita establecer la lista __all__ con los nombres de lo que desea exportar. es decir, __all__ = ["xyzzy"]

0

¿Por qué importar desde hhh.foo.bar en hhh.foo? import bar debería ser suficiente allí.

Cuestiones relacionadas