Jednym ze źródeł trudności z tym pytaniem jest to, że masz program o nazwie bar/bar.py
: import bar
importu albo bar/__init__.py
albo bar/bar.py
, w zależności od tego, gdzie to jest zrobione, co sprawia, że jest to trochę kłopotliwe, aby śledzić, które a
jest bar.a
.
Oto jak to działa:
Kluczem do zrozumienia tego, co się dzieje, aby uświadomić sobie, że w twojej __init__.py
,
from bar import a
w efekcie robi coś podobnego
a = bar.a
# … where bar = bar/bar.py (as if bar were imported locally from __init__.py)
i definiuje nową zmienną ( bar/__init__.py:a
jeśli chcesz). W ten sposób twój from bar import a
in __init__.py
wiąże nazwę bar/__init__.py:a
z oryginalnym bar.py:a
obiektem ( None
). Dlatego możesz to zrobić from bar import a as a2
w __init__.py
: w tym przypadku jest jasne, że masz obie bar/bar.py:a
i odrębną nazwę zmiennej bar/__init__.py:a2
(w twoim przypadku nazwy dwóch zmiennych po prostu są a
, ale nadal istnieją w różnych przestrzeniach nazw: w __init__.py
, są bar.a
i a
).
Teraz, kiedy to zrobisz
import bar
print bar.a
uzyskujesz dostęp do zmiennej bar/__init__.py:a
(ponieważ import bar
importuje twoją bar/__init__.py
). To jest zmienna, którą modyfikujesz (do 1). Nie dotykasz zawartości zmiennej bar/bar.py:a
. Więc kiedy później to zrobisz
bar.foobar()
wywołujesz bar/bar.py:foobar()
, która uzyskuje dostęp do zmiennej a
z bar/bar.py
, która jest nadal None
(gdy foobar()
jest zdefiniowana, wiąże nazwy zmiennych raz na zawsze, więc a
in bar.py
jest bar.py:a
, a nie żadna inna a
zmienna zdefiniowana w innym module - ponieważ może być wiele a
zmiennych we wszystkich zaimportowanych modułach ). Stąd ostatnie None
wyjście.
Wniosek: najlepiej jest uniknąć wszelkich niejasności import bar
, nie mając żadnego bar/bar.py
modułu (ponieważ bar.__init__.py
sprawia, że katalog bar/
jest już pakietem, za pomocą którego można również importować import bar
).