2011-07-18 30 views
7

Giả sử cấu trúc mã sau:Tại sao hai nhập khẩu Python này hoạt động khác nhau?

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

tôi chạy python bên 1/ và làm import hhh.foo.baz. Nó không thành công:

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' 

Bây giờ tôi thay thế baz.py với:

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

và một lần nữa làm import hhh.foo.baz. Bây giờ nó hoạt động, mặc dù tôi đang tải cùng một mô-đun, chỉ gắn một tên khác.

Điều này có nghĩa là sự khác biệt giữa import modulefrom module import name không chỉ là số nhận dạng? Chính xác thì chuyện gì đang xảy ra ở đây vậy?

(Tôi biết tôi có thể sử dụng hàng nhập khẩu liên quan đến làm việc xung quanh tất cả điều này, nhưng tôi vẫn muốn hiểu được cơ chế. Ngoài ra tôi không thích nhập khẩu tương đối, và cũng như thế PEP 8.)

Trả lời

8

Khi bạn viết from hhh.foo.bar import xyzzy Trình thông dịch Python sẽ cố gắng tải xyzzy từ mô-đun hhh.foo.bar. Nhưng nếu bạn viết import hhh.foo.bar as bar, nó sẽ cố gắng đầu tiên tìm thấy bar trong mô-đun hhh.foo. Vì vậy, nó đánh giá hhh.foo, làm from hhh.foo.baz import * . hhh.foo.baz cố gắng đánh giá hhh.foo, hhh.foo cố gắng đánh giá hhh.foo.baz, nhập vòng tuần hoàn, ngoại lệ.

+0

Phải, do đó, có sự khác biệt về ngữ nghĩa. Cảm ơn! –

0

trong 1/hhh/foo/__init__.py bạn cần đặt danh sách __all__ với tên của những gì bạn muốn xuất. tức là __all__ = ["xyzzy"]

0

Tại sao bạn nhập từ hhh.foo.bar trong hhh.foo? import bar phải đủ ở đó.

Các vấn đề liên quan