Одним із джерел труднощів з цим питанням є те, що у вас є програма з ім’ям bar/bar.py
: import bar
import bar/__init__.py
або bar/bar.py
, залежно від того, де це зроблено, що робить трохи громіздким відстеження, що a
саме bar.a
.
Ось як це працює:
Ключем до розуміння того, що відбувається, є усвідомлення того, що у вашому __init__.py
,
from bar import a
фактично робить щось подібне
a = bar.a
# … where bar = bar/bar.py (as if bar were imported locally from __init__.py)
і визначає нову змінну ( bar/__init__.py:a
за бажанням). Таким чином, ваш from bar import a
in __init__.py
прив'язує ім'я bar/__init__.py:a
до вихідного bar.py:a
об'єкта ( None
). Саме тому ви можете зробити from bar import a as a2
в __init__.py
: в цьому випадку, очевидно , що у вас є як bar/bar.py:a
і в виразну ім'я змінної bar/__init__.py:a2
(в вашому випадку, імена двох змінних просто виявилися обидва a
, але вони по- , як і раніше живуть в різних просторах імен: в __init__.py
, вони є bar.a
і a
).
Тепер, коли ви це зробите
import bar
print bar.a
ви отримуєте доступ до змінної bar/__init__.py:a
(оскільки import bar
імпортує вашу bar/__init__.py
). Це змінна, яку ви змінюєте (до 1). Ви не торкаєтесь змісту змінної bar/bar.py:a
. Отже, коли ви згодом це зробите
bar.foobar()
ви викликаєте bar/bar.py:foobar()
, який отримує доступ до змінної a
з bar/bar.py
, яка все ще є None
(коли foobar()
визначена, вона пов'язує імена змінних раз і назавжди, тому a
in bar.py
є bar.py:a
, а не будь-яка інша a
змінна, визначена в іншому модулі - оскільки a
у всіх імпортованих модулях може бути багато змінних ). Звідси останній None
вихід.
Висновок: найкраще уникати будь-якої неоднозначності import bar
, не маючи жодного bar/bar.py
модуля (оскільки bar.__init__.py
каталог bar/
вже робить пакетом, з яким ви також можете імпортувати import bar
).