ProgrammierungBackend-Entwickler

Was ist die Übergabe von Argumenten durch Referenz und durch Wert in Python? Wie implementiert Python diesen Mechanismus und warum ist es wichtig, sie beim Entwerfen von Funktionen zu unterscheiden?

Bestehen Sie Vorstellungsgespräche mit dem Hintsage-KI-Assistenten

Antwort.

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.

Hintergrund

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).

Problem

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.

Lösung

In Python sind die Werte von Funktionsparametern Referenzen auf die Objekte, die an die Funktion übergeben werden. Das bedeutet:

  • Wenn das Objekt veränderbar (mutable: list, dict, set…) ist — kann es innerhalb der Funktion modifiziert werden, und dies wird sich nach außen hin auswirken.
  • Wenn das Objekt unveränderbar (immutable: int, str, tuple, frozenset) ist, wird der Versuch, es innerhalb der Funktion zu ändern, ein neues Objekt erzeugen und das äußere Objekt nicht berühren.

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:

  • Veränderbare Objekte können innerhalb der Funktion geändert werden — diese Änderungen sind sichtbar nach außen.
  • Unveränderbare Objekte werden von der Funktion nicht berührt — es werden nur neue Objekte erstellt.
  • Python kopiert Argumente niemals automatisch, auch veränderbare Strukturen werden immer „durch Referenz“ übergeben.

Fangfragen.

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]

Typische Fehler und Antipatterns

  • Verwendung von veränderbaren Standardargumenten (wie im letzten Beispiel).
  • Erwartung, dass eine Funktion das übergebene list oder dict nicht ändert, während sie es tatsächlich modifiziert.
  • Verwirrung der Effekte von Funktionen beim Arbeiten mit veränderbaren und unveränderbaren Objekten.

Beispiel aus dem Leben

Negativer Fall

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:

  • Schnelle Ausführung, kein Kopieren von Daten.

Nachteile:

  • Unerwartete Nebeneffekte, Bugs im umfangreichen Code, wenn jemand die Modifikationen des Arguments nicht kennt.

Positiver Fall

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:

  • Keine unerwünschten Nebeneffekte, das Original ist geschützt.

Nachteile:

  • Bei großen Objekten — Speicher-/Zeitkosten für das Kopieren.