Einfache rekursive Funktion komisches Verhalten

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
BlackJack

@Denn1s: Weil Du bei `A` eine Liste mit einer 12 drin übergeben hast und damit *diese* Liste verwendet wurde und bei `B` hast Du nichts übergeben womit dort die Default-Liste verwendet wurde. Das sind zwei verschiedene Listen.

Vielleicht hilft ja dieses sinnfreie Minimalbeispiel:

Code: Alles auswählen

In [5]: def f(parrot, spam=[]):
   ...:     spam.append(parrot)
   ...:     return spam
   ...: 

In [6]: f.func_defaults
Out[6]: ([],)

In [7]: f(42)
Out[7]: [42]

In [8]: f.func_defaults
Out[8]: ([42],)

In [9]: f(23)
Out[9]: [42, 23]

In [10]: f.func_defaults
Out[10]: ([42, 23],)

In [11]: f(4711, [])
Out[11]: [4711]

In [12]: f.func_defaults
Out[12]: ([42, 23],)

In [13]: f.func_defaults[0][0] = 'hallo'

In [14]: f('welt')
Out[14]: ['hallo', 23, 'welt']
Bei der Ausführung des ``def`` bei [5] wird eine Liste erstellt und im Funktionsobjekt gespeichert. Kann man bei [6] sehen (bin mir fast sicher dass der Name `func_defaults` ein Implementierungsdetail ist, also besser keinen Code schreiben der sich darauf verlässt).

Immer wenn man jetzt `f()` ohne ein Argument für `spam` aufruft wird diese Liste an den lokalen Namen `spam` gebunden. Ansonsten halt der Wert den man übergeben hat.

Wenn man das Objekt in der Methode verändert, nun ja, dann verändert man natürlich das Objekt. Wie man sowohl am Effekt bei den Aufrufen, als auch beim nachsehen in den Funktionsinterna deutlich sehen kann. Und wenn man direkt in den Innereien herum pfuscht, sieht man das natürlich auch bei den folgenden Aufrufen.
Denn1s
User
Beiträge: 17
Registriert: Mittwoch 8. Januar 2014, 14:08

Besten Dank, hat sehr weitergeholfen!!! Ich glaube nun muss ich noch einiges in meinem Code korrigieren :)
Schönes WE Euch allen!
BlackJack

Offizielle API um an die Werte zu kommen:

Code: Alles auswählen

In [20]: import inspect

In [21]: inspect.getargspec(f)
Out[21]: ArgSpec(args=['parrot', 'spam'], varargs=None, keywords=None, defaults=(['hallo', 23, 'welt'],))
Antworten