Один источник трудностей с этим вопросом является то , что у вас есть программа под названием bar/bar.py: import barимпорт либо 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).