开发者

Why do these two Python imports work differently?

Assume the following code structure:

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

I run python inside 1/ and do import hhh.foo.baz. It fails:

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'

Now I repl开发者_开发百科ace baz.py with:

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

and again do import hhh.foo.baz. Now it works, although I’m loading the same module, only binding a different name.

Does this mean that the distinction between import module and from module import name goes beyond just identifiers? What exactly is going on here?

(I know I can use relative imports to work around all this, but still I’d like to understand the mechanics. Plus I don’t like relative imports, and neither does PEP 8.)


When you write from hhh.foo.bar import xyzzy Python interpreter will try to load xyzzy from module hhh.foo.bar. But if you write import hhh.foo.bar as bar it will try first to find bar in hhh.foo module. So it evaluates hhh.foo, doing from hhh.foo.baz import * . hhh.foo.baz tries to evaluate hhh.foo, hhh.footries to evaluate hhh.foo.baz, cyclic imports, exception.


in 1/hhh/foo/__init__.py you need to set the __all__ list with the names of what you want to export. i.e. __all__ = ["xyzzy"]


Why do you import from hhh.foo.bar in hhh.foo? import bar should suffice there.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜