Một nguồn khó khăn với câu hỏi này là bạn có một chương trình mang tên bar/bar.py
: import bar
nhập khẩu hoặc bar/__init__.py
hoặc bar/bar.py
, tùy thuộc vào nơi nó được thực hiện, mà làm cho nó một chút rườm rà để theo dõi mà a
là bar.a
.
Đây là cách nó làm việc:
Chìa khóa để hiểu những gì xảy ra là để nhận ra rằng trong bạn __init__.py
,
from bar import a
trên thực tế, điều gì đó giống như
a = bar.a
# … where bar = bar/bar.py (as if bar were imported locally from __init__.py)
và xác định một biến mới ( bar/__init__.py:a
, nếu bạn muốn). Vì vậy, bạn from bar import a
ở __init__.py
với phím tắt tên bar/__init__.py:a
với bản gốc bar.py:a
đối tượng ( None
). Đây là lý do tại sao bạn có thể làm from bar import a as a2
trong __init__.py
: trong trường hợp này, rõ ràng là bạn có cả hai bar/bar.py:a
và một tên biến riêng biệtbar/__init__.py:a2
(trong trường hợp của bạn, tên của hai biến chỉ xảy ra với cả hai a
, nhưng chúng vẫn tồn tại trong các không gian tên khác nhau: in __init__.py
, chúng bar.a
và a
).
Bây giờ, khi bạn làm
import bar
print bar.a
bạn đang truy cập biến bar/__init__.py:a
(vì import bar
nhập của bạn bar/__init__.py
). Đây là biến bạn sửa đổi (thành 1). Bạn không chạm vào nội dung của biến bar/bar.py:a
. Vì vậy, khi bạn sau đó làm
bar.foobar()
bạn gọi bar/bar.py:foobar()
, truy cập biến a
từ bar/bar.py
đó vẫn là biến None
(khi foobar()
được định nghĩa, nó liên kết các tên biến một lần và mãi mãi, vì vậy, a
trong bar.py
là bar.py:a
, không phải bất kỳ a
biến nào khác được xác định trong mô-đun khác — vì có thể có nhiều a
biến trong tất cả các mô-đun đã nhập ). Do đó None
đầu ra cuối cùng .
Kết luận: tốt nhất là tránh bất kỳ sự mơ hồ nào trong đó import bar
, bằng cách không có bất kỳ bar/bar.py
mô-đun nào (vì đã bar.__init__.py
tạo thư mục bar/
thành một gói nên bạn cũng có thể nhập với import bar
).