ProgrammazioneSviluppatore Backend

Cosa sono i metodi magici (metodi dunder) in Python, come vengono utilizzati e perché è importante sovrascriverli nelle proprie classi? Fornisci esempi di utilizzo e spiega le sfumature da considerare nella loro implementazione.

Supera i colloqui con l'assistente IA Hintsage

Risposta.

I metodi magici (o metodi dunder – da double underscore) sono metodi speciali il cui nome inizia e termina con due trattini bassi, ad esempio, __init__, __str__, __add__. Consentono di integrare le istanze delle proprie classi nella sintassi e nel comportamento di Python: definire la reazione alle operazioni aritmetiche, ai confronti, alla conversione in stringhe, al lavoro con i protocolli delle collezioni, ecc.

Esempio:

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) # Chiamerà v1.__add__(v2), restituirà Vector(4, 6)

Domanda insidiosa.

Se non si implementa __eq__ nella propria classe, come verranno confrontate le sue istanze tra loro con l'operatore ==?

Risposta: Per impostazione predefinita, l'operatore == confronta gli oggetti per identità (indirizzo di memoria, analogamente all'operatore is), se non viene sovrascritto il metodo magico __eq__.

class A: pass print(A() == A()) # False, anche se gli oggetti "sembrano identici"

Esempi di errori reali a causa dell'ignoranza delle sottigliezze dell'argomento.


Storia

Nel progetto in cui era necessario confrontare le strutture di un grafo, non è stato implementato il metodo __eq__. Questo ha portato a risultati incorretti durante il controllo "il nodo è già stato aggiunto", poiché l'operatore == confrontava gli oggetti per id, e non per contenuto.


Storia

Durante la scrittura di un'API REST, abbiamo serializzato un oggetto in una stringa per il log tramite str(obj), ma abbiamo dimenticato di definire __str__. Di conseguenza, veniva visualizzato un testo illeggibile <MyObj object at 0x...>, rendendo difficile la diagnosi dei problemi.


Storia

In una libreria per calcoli matematici, è stato implementato solo __add__, ma è stato dimenticato __iadd__ per l'operatore +=. Di conseguenza, l'espressione v += w non si comportava come previsto (veniva creato un nuovo oggetto, non aggiornato quello esistente), il che ha portato a perdite di memoria in calcoli complessi.