Python-Standardargumente werden nicht bei jedem Aufruf initialisiert

Ich schrieb Code in Python und dachte: "Ist es wirklich?"

def wrap_list(value, base_list = []):
    base_list.append(value)
    return base_list

Angenommen, Sie haben einen solchen Code. Wenn Sie dies oft aufrufen, lassen Sie das zweite Argument weg:

print(wrap_list(1)) # => [1]
print(wrap_list(2)) # => [1, 2]

Das Ergebnis ist. Ich möchte, dass es das zweite Mal "[2]" ist.

Sie können sehen, was passiert, indem Sie die Objekt-ID mit der Funktion "id" anzeigen.

def wrap_list(value, base_list = []):
    print(id(base_list)) # debug print
    base_list.append(value)
    return base_list

wrap_list(1) # => 4373211008
wrap_list(2) # => 4373211008

Die Objekt-ID von "base_list" ist in beiden Aufrufen gleich. Mit anderen Worten, nicht für jeden Anruf wird eine leere Liste erstellt, sondern nur einmal.

Übrigens habe ich es auch bei Ruby versucht:

def wrap_list(value, base_list = [])
  puts base_list.object_id
  base_list << value
end

wrap_list(1) # => 70218064569220
wrap_list(2) # => 70218064588580

Dies scheint für jeden Anruf generiert zu werden.

Ich glaube nicht, dass ich Code wie den oben in Python schreiben würde:

class WrappedList(object):
    def __init__(self, initial = []):
        self.list = initial

    def append(self, value):
        self.list.append(value)

Natürlich passiert in solchen Fällen dasselbe, daher müssen Sie vorsichtig sein.

Das grundlegende Problem besteht darin, dass es nicht für jeden Aufruf initialisiert wird und die Problemumgehung einfach darin besteht, "keine destruktiven Operationen auszuführen". Wenn Sie eine destruktive Operation benötigen, können Sie das Standardargument selbst auf "Keine" setzen. Wenn es "Keine" ist, initialisieren Sie es mit einer leeren Liste und so weiter.

Recommended Posts

Python-Standardargumente werden nicht bei jedem Aufruf initialisiert
Unter CentOS (RHEL) 8 können keine Python- und Pip-Befehle verwendet werden
a () und a .__ call__ () sind nicht gleichwertig
Erstellen einer Python-Umgebung unter Ubuntu (wenn pip nicht die Standardeinstellung war)
Rufen Sie C / C ++ von Python auf dem Mac auf
Alle Python-Argumente werden als Referenz übergeben
Virtualenv funktioniert nicht unter Python 3.5 (Windows)
Jinja2 2.9.6 funktioniert nicht mit der Lambda Python 3-Serie
Wann werden die Standardargumente in Python gebunden? Wenn die Variable im Abschluss gebunden ist, wird die Auswertung verschoben.