Одним із джерел труднощів з цим питанням є те, що у вас є програма з ім’ям bar/bar.py: import barimport 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 ain __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()визначена, вона пов'язує імена змінних раз і назавжди, тому ain bar.pyє bar.py:a, а не будь-яка інша aзмінна, визначена в іншому модулі - оскільки aу всіх імпортованих модулях може бути багато змінних ). Звідси останній Noneвихід.
Висновок: найкраще уникати будь-якої неоднозначності import bar, не маючи жодного bar/bar.pyмодуля (оскільки bar.__init__.pyкаталог bar/вже робить пакетом, з яким ви також можете імпортувати import bar).