Me desconcierta cómo se manejan las importaciones circulares en Python. Intenté extraer una pregunta mínima y no creo que esta variante exacta se haya preguntado antes. Básicamente, estoy viendo una diferencia entreDiferencia entre "importar lib.foo" e "importar lib.foo como f" en Python
import lib.foo
y
import lib.foo as f
cuando tengo una dependencia circular entre lib.foo
y lib.bar
. Esperaba que ambos funcionaran de la misma manera: el módulo (posiblemente a mitad de inicializado) se encontraría en sys.modules
y se colocaría en el espacio de nombres local. (A partir de las pruebas me di cuenta de que realmente pone import lib.foo
lib
en el espacio de nombres local, -. Bien, con la sintaxis que lo haré de todos modos lib.foo.something
)
Sin embargo, si ya está en lib.foo
sys.modules
, a continuación, import lib.foo as f
intenta acceder foo
como un atributo en lib
y aumenta AttributeError. ¿Por qué el comportamiento (aparentemente) depende de la presencia en sys.modules
?
Además, ¿dónde está documentado este comportamiento? No creo que el Python import
statement reference explique este comportamiento, o al menos no pude extraerlo :-)
En general, estoy intentando cambiar un código base para usar el estilo oft recommended donde importa módulos, no símbolos en los módulos:
from project.package import moduleA
from project.package import moduleB
Pero eso falla cuando hay importaciones circulares entre los dos módulos. Esperaba que funcionara siempre que las definiciones de nivel superior en los dos módulos no dependieran entre sí (por ejemplo, ninguna subclase en moduleB
con una clase base en moduleA
).
escritura de la prueba:
#!/bin/sh
rm -r lib; mkdir lib
touch lib/__init__.py
cat > lib/foo.py <<EOF
# lib.foo module
print '{ foo'
#import lib.bar # works
import lib.bar as b # also works
#from lib import bar # also works
print 'foo }'
EOF
cat > lib/bar.py <<EOF
# lib.bar module
print '{ bar'
#import lib.foo # works
import lib.foo as f # AttributeError: 'module' object has no attribute 'foo'
#from lib import foo # ImportError: cannot import name foo
print 'bar }'
EOF
python -c 'import lib.foo'
Enlace http://google-styleguide.googlecode.com/svn/trunk/pyguide.html?showone=Imports#Imports está roto - sería bueno leer –