Das Verständnis, wie Python Argumente in Funktionen übergibt, ist entscheidend, um unerwartete Änderungen an Daten zu vermeiden und um den Code korrekt zu entwerfen.
In traditionellen Programmiersprachen wie C oder Java wird die Übergabe durch Wert (copy by value) oder durch Referenz (copy by reference) verwendet. Python hat jedoch ein anderes Modell — call by object reference (manchmal auch „call by sharing“ genannt).
Viele Entwickler denken fälschlicherweise, dass Python Argumente immer entweder durch Referenz oder durch Wert übergibt. Dies führt unweigerlich zu Situationen, in denen veränderbare Objekte unerwartet im aufrufenden Code modifiziert werden.
In Python sind die Werte von Funktionsparametern Referenzen auf die Objekte, die an die Funktion übergeben werden. Das bedeutet:
Beispiel:
# list - veränderbar (mutable) def add_item(lst): lst.append(42) my_list = [1, 2, 3] add_item(my_list) print(my_list) # [1, 2, 3, 42] # int - unveränderbar (immutable) def add_num(x): x = x + 1 num = 10 add_num(num) print(num) # 10
Wichtige Merkmale:
Werden in Python Argumente immer durch Referenz übergeben?
Nein, in Python werden Referenzen auf Objekte übergeben, und wie sich das Objekt verhält, hängt davon ab, ob es veränderbar ist oder nicht. Ein unveränderbares Objekt erstellt bei jeder Änderung ein neues Objekt.
Kann man in einer Funktion ein veränderbares Argument neu zuweisen, so dass es das äußere Objekt beeinflusst?
Nein. Wenn Sie innerhalb der Funktion dem Parameter einen neuen Wert zuweisen, wird das äußere Objekt nicht geändert — Sie ändern nur die lokale Referenz.
Beispiel:
def reassign_list(lst): lst = [99, 100] my_list = [1, 2, 3] reassign_list(my_list) print(my_list) # [1, 2, 3]
Warum kann eine Funktion, die standardmäßig ein Listensystem erwartet, bei mehrfachen Aufrufen seltsam funktionieren?
Weil der Standardwert einmal erstellt wird — bei der Definition der Funktion, und wenn er geändert wird (z. B. ein Element hinzugefügt wird), ändert sich dieser für alle nachfolgenden Aufrufe.
def add_element(x, cache=[]): cache.append(x) return cache print(add_element(1)) # [1] print(add_element(2)) # [1, 2]
Ein Programmierer übergibt einer Funktion eine Liste und erwartet, dass seine originale Liste nicht geändert wird, aber die Funktion fügt ein Element hinzu.
Vorteile:
Nachteile:
Ein Programmierer kopiert die Liste innerhalb der Funktion absichtlich, wenn er etwas zurückgeben, aber das Original nicht ändern möchte:
def process_data(data): data = data.copy() # oder list(data) # sichere Arbeit mit der Kopie data.append('Bericht') return data
Vorteile:
Nachteile: