Seite 1 von 1

Default Parameter list

Verfasst: Dienstag 6. September 2011, 10:10
von Gregorrr
Huch, was ist da los:
Ich habe einen list Default-Parameter, der mutable ist.

Code: Alles auswählen

def append_num(x, items=[]):
    items.append(x)
    return items

append_num(1) # [1]
append_num(2) # [1, 2]
append_num(3) # [1, 2, 3]
Warum wird nicht jedes mal eine neue Liste mit leerem Inhalt erstellt? Ich mein, eigentlich müsste doch der GC hingehen und die lokale Variable items, die ja keinen Scope mehr hat, beseitigen.

Danke schonmal!

Re: Default Parameter list

Verfasst: Dienstag 6. September 2011, 10:19
von /me
items wird beim ersten Aufruf fest gebunden. Um hier das von dir gewünschte Verhalten zu bekommen bietet sich folgender Code an.

Code: Alles auswählen

def append_num(x, items=None):
    if not items:
        items = []
    items.append(x)
    return items

Re: Default Parameter list

Verfasst: Dienstag 6. September 2011, 11:17
von lunar
@Gregorrr: "items" ist nicht lokal. Der Ausdruck für den Standardwert wird bei der Erzeugung der Funktion (und nicht bei deren Aufruf) ausgewertet. Das Ergebnis dieses Ausdrucks wird dann an das Funktionsobjekt gebunden, und somit global. Für eine vollständige Erklärung siehe Default Parameter Values in Python von Fredrik Lundh.

Die übliche Vorgehensweise zur Vermeidung dieses Effekts hat /me Dir bereits gezeigt, anzumerken ist noch, dass dieser Effekt jeden veränderbaren Typen betrifft, also nicht nur Listen, sondern auch Wörterbücher, Mengen, und Klassen-Exemplare. Daher ist das von /me gezeigte Idiom der übliche Weg, um Standardwerte jeglicher Art für Argumente vorzugeben. Nur bei wenigen Typen (Zeichenketten, Zahlen und Tupel sowie davon abgeleitete Klassen wie "collections.namedtuple()") gibt man den Standardwert direkt an.

Re: Default Parameter list

Verfasst: Dienstag 6. September 2011, 11:23
von EyDu
Stat `not items` sollte besser `items is not None` verwendet werden. Vielleicht möchte man tatsächlich mal eine leere Liste übergeben, welche in-place verändert wird.

Re: Default Parameter list

Verfasst: Dienstag 6. September 2011, 11:50
von Gregorrr
Wow, vielen vielen Dank @lunar. Genau diese Erklärung habe ich gesucht. :)
Und danke /me und Eydu für die Idiome.

Die funktionalen Bestandteile von Python sind eine spannende Sache, vor allem wenn man aus der Java Welt kommt. :)