2011-07-18 14 views
7

Załóżmy następującą strukturę kodu:Dlaczego te dwa importowania Python działają inaczej?

#### 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 

biegnę python wewnątrz 1/ i zrobić import hhh.foo.baz. To się nie powiedzie:

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' 

Teraz zastąpić baz.py z:

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

i ponownie zrobić import hhh.foo.baz. Teraz działa, chociaż ładuję ten sam moduł, tylko wiążę inną nazwę.

Czy to oznacza, że ​​rozróżnienie pomiędzy import module a from module import name wykracza poza zwykłe identyfikatory? Co dokładnie się tutaj dzieje?

(wiem, że mogę korzystać z importu w stosunku do obejścia tego wszystkiego, ale chciałbym zrozumieć mechanikę. Plus nie lubię importu względne, a nie robi PEP 8.)

Odpowiedz

8

When piszesz from hhh.foo.bar import xyzzy Interpreter języka Python spróbuje załadować xyzzy z modułu hhh.foo.bar. Ale jeśli napiszesz import hhh.foo.bar as bar, najpierw spróbujesz znaleźć bar w module hhh.foo. Więc ocenia hhh.foo, robiąc from hhh.foo.baz import * . hhh.foo.baz próbuje ocenić hhh.foo, hhh.foo próbuje ocenić hhh.foo.baz, cykliczne importowanie, wyjątek.

+0

Dobrze, więc jest różnica w semantykach. Dzięki! –

0

w 1/hhh/foo/__init__.py należy ustawić listę __all__ z nazwą tego, co chcesz wyeksportować. tj. __all__ = ["xyzzy"]

0

Dlaczego importujesz z hhh.foo.bar w hhh.foo? import bar powinno wystarczyć.

Powiązane problemy