Dzieje się tak, ponieważ kompilacja w Pythonie jest wykonywana przez wykonanie kodu opisowego.
Jeśli ktoś tak powiedział
def f(x = {}):
....
byłoby całkiem jasne, że za każdym razem chciałeś nowej tablicy.
Ale co jeśli powiem:
list_of_all = {}
def create(stuff, x = list_of_all):
...
Tutaj zgaduję, że chcę tworzyć rzeczy na różnych listach i mieć jeden globalny catch-all, gdy nie podam listy.
Ale jak zgadłby to kompilator? Po co więc próbować? Moglibyśmy polegać na tym, czy to się nazywa, czy nie, i czasem może to pomóc, ale tak naprawdę to tylko zgadywanie. Jednocześnie istnieje dobry powód, aby nie próbować - spójności.
W tej chwili Python po prostu wykonuje kod. Zmienna list_of_all jest już przypisana do obiektu, więc obiekt jest przekazywany przez odwołanie do kodu, który domyślnie x, w taki sam sposób, jak wywołanie dowolnej funkcji otrzyma odwołanie do obiektu lokalnego o nazwie tutaj.
Gdybyśmy chcieli odróżnić nienazwany od nazwanego przypadku, wymagałoby to kodu przy kompilacji wykonującego przypisanie w znacznie inny sposób niż jest wykonywany w czasie wykonywania. Dlatego nie robimy specjalnego przypadku.