Spróbuje wytłumaczyć w prosty sposób.
Python ładuję funkcję i wartość domyślną tylko raz do pamięci.
Później te zera są dodawane do listy utworzonej podczas ładowania funkcji. Lista jest po prostu definiowana tylko raz.
Może użyj http://pythontutor.com/visualize.html to bardzo fajna strona, gdzie można zobaczyć, jak python zarządza pamięcią.
Co do porównania z Ruby'im , wynika to z tego jak python zarządza pamięcią i różnic w tym temacie pomiędzy tymi (rzekomo) podobnymi językami.
Aby w python'ie uzyskać taki wynik o jaki Ci chodzi możesz użyć tego kodu.
def a(b=None):
if b is None:
b = []
b.append(0)
print(b)
a()
a()
a()
Jest to tylko przykład, metod jest więcej.
Nie umiem dobrze tłumaczyć, ale się starałem. Jak coś będzie nie jasne, napisz.
Pozdrawiam.