ProgrammierungBackend Entwickler

Was sind magische Methoden (Dunder-Methoden) in Python, wie werden sie verwendet und warum sollten sie in eigenen Klassen überschrieben werden? Geben Sie Beispiele für ihre Anwendung und erklären Sie die Nuancen, die bei ihrer Implementierung berücksichtigt werden sollten.

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

Antwort.

Magische Methoden (oder Dunder-Methoden – von double underscore) sind spezielle Methoden, deren Namen mit zwei Unterstrichen beginnen und enden, zum Beispiel __init__, __str__, __add__. Sie ermöglichen es, Instanzen eigener Klassen in die Syntax und das Verhalten von Python einzubetten: sie definieren die Reaktion auf arithmetische Operationen, Vergleiche, die Umwandlung in Strings, die Arbeit mit Sammlungsprotokollen usw.

Beispiel:

class Vector: def __init__(self, x, y): self.x = x self.y = y def __add__(self, other): return Vector(self.x + other.x, self.y + other.y) def __str__(self): return f"Vector({self.x}, {self.y})" v1 = Vector(1, 2) v2 = Vector(3, 4) print(v1 + v2) # Ruft v1.__add__(v2) auf, gibt Vector(4, 6) zurück

Fangfrage.

Wenn __eq__ in der eigenen Klasse nicht implementiert ist, wie werden dann die Instanzen untereinander mit dem Operator == verglichen?

Antwort: Standardmäßig vergleicht der Operator == Objekte anhand der Identität (Adresse im Speicher, ähnlich dem Operator is), wenn die magische Methode __eq__ nicht überschrieben wird.

class A: pass print(A() == A()) # False, obwohl die Objekte "gleich zu sein scheinen"

Beispiele für echte Fehler aufgrund mangelnden Wissens über die Details des Themas.


Geschichte

In einem Projekt, in dem die Strukturen eines Graphen verglichen werden mussten, wurde die Methode __eq__ nicht implementiert. Dadurch erhielt man bei der Überprüfung, "ob der Knoten bereits hinzugefügt wurde", ein inkorrektes Ergebnis, da der Operator == die Objekte nach id verglich, nicht nach Inhalt.


Geschichte

Bei der Erstellung einer REST-API wurde ein Objekt zur Protokollierung in einen String umgewandelt über str(obj), aber es wurde versäumt, __str__ zu definieren. Infolgedessen wurde ein unlesbarer Text <MyObj object at 0x...> ausgegeben, was die Fehlersuche erschwerte.


Geschichte

In einer Bibliothek für mathematische Berechnungen wurde nur __add__ implementiert, aber __iadd__ für den Operator += vergessen. Infolgedessen funktionierte der Ausdruck v += w nicht wie erwartet (es wurde ein neues Objekt erstellt, das alte wurde nicht aktualisiert), was zu Speicherlecks in komplizierten Berechnungen führte.