Uma fonte de dificuldade com essa questão é que você tem um programa chamado bar/bar.py: import barimporta bar/__init__.pyou bar/bar.py, dependendo de onde é feito, o que torna um pouco complicado rastrear qual aé bar.a.
É assim que funciona:
A chave para entender o que acontece é perceber que em seu __init__.py,
from bar import a
na verdade, faz algo como
a = bar.a
# … where bar = bar/bar.py (as if bar were imported locally from __init__.py)
e define uma nova variável ( bar/__init__.py:ase desejar). Assim, seu from bar import ain __init__.pyassocia o nome bar/__init__.py:aao bar.py:aobjeto original ( None). É por isso que você pode fazer from bar import a as a2em __init__.py: neste caso, é claro que você tem ambos bar/bar.py:ae um nome de variável distintobar/__init__.py:a2 (no seu caso, os nomes das duas variáveis são ambos a, mas ainda vivem em namespaces diferentes: em __init__.py, eles são bar.ae a).
Agora, quando você fizer
import bar
print bar.a
você está acessando a variável bar/__init__.py:a(já que import barimporta o seu bar/__init__.py). Esta é a variável que você modifica (para 1). Você não está tocando o conteúdo da variável bar/bar.py:a. Então, quando você posteriormente fizer
bar.foobar()
você chama bar/bar.py:foobar(), que acessa a variável ade bar/bar.py, que ainda é None(quando foobar()é definida, vincula nomes de variáveis de uma vez por todas, então o ain bar.pyé bar.py:a, não qualquer outra avariável definida em outro módulo - como pode haver muitas avariáveis em todos os módulos importados ) Daí a última Nonesaída.
Conclusão: é melhor evitar qualquer ambigüidade no import bar, por não ter nenhum bar/bar.pymódulo (já que bar.__init__.pytorna o diretório bar/um pacote, com o qual você também pode importar import bar).