Seite 1 von 1

Verständnisfrage Parameter mit default Wert

Verfasst: Donnerstag 13. Juni 2019, 19:14
von ThomasL
Wer von den Profis kann mir das erklären?
Dieser Code

Code: Alles auswählen

def f(a, L=[]):
    L.append(a)
    return L

f(1, [])
f(2, [])
print(f(3, []))
liefert als Ausgabe Warum bekommt man als Ausgabe

Code: Alles auswählen

[1,2,3]
wenn man die leere Liste als Argument weglässt?

Code: Alles auswählen

f(1)
f(2)
print(f(3))
Warum wird die Zuweisung einer leeren Liste an L beim wiederholten Aufruf der Funktion f "ignoriert"?
Beim ersten Mal wird der Defaultwert ja genommen, sonst gebe es ja einen Fehler.

Re: Verständnisfrage Parameter mit default Wert

Verfasst: Donnerstag 13. Juni 2019, 19:21
von Sirius3
Die Objekte für die Defaultwerte werden zum Zeitpunkt der Definition erzeugt, das ist also äquivalent zu:

Code: Alles auswählen

globales_L = {}
def f(a, L=globales_L):
    L.append(a)
    return L
man hat also eine globale Variable, und wie bei allen globalen Variablen gilt, es sollte sie nicht geben, das bedeutet, dass man Defaultwert-Objekte nicht verändern sollte.

Re: Verständnisfrage Parameter mit default Wert

Verfasst: Donnerstag 13. Juni 2019, 19:33
von sparrow
Das mit dem "Initialisieren bei Definition zur Laufzeit" fällt einem immer dann auf die Füße, wenn es keine einfache Wertzuweisung ist. Bei Collections, aber auch bei dem Rückgabewert von Funktionen.
Ich bin da mal irgendwann schmerzlich drüber gestolpert, als ich in einer Funktion den aktuellen Zeitpunkt als Default-Wert brauchte und der entsprechende aufruf von time.time() nur einmal, nämlich während der Definition der Funktion im Interpreter ausgewertet wurde.

Ich löse das so:

Code: Alles auswählen

def f(a, L=None):
    L = [] if L is None else L
    L.append(a)
    return L

Re: Verständnisfrage Parameter mit default Wert

Verfasst: Donnerstag 13. Juni 2019, 19:46
von ThomasL
Vielen Dank, jetzt bin ich wieder etwas schlauer.
Habe mal ein print(id(L)) in die Funktion eingefügt
und ohne die leere Liste als 2.tes Argument wird immer die gleiche Id der leeren Default-Liste ausgegeben.
Faszinierend! :-)