Vai al contenuto principale

Metodi Dunder in Python: comandi speciali da conoscere

Scopri come i metodi con doppio underscore di Python permettono ai tuoi oggetti personalizzati di funzionare naturalmente con le operazioni integrate, dalla stampa all'aritmetica. Scopri come questi metodi magici semplificano il design delle classi e sbloccano potenti comportamenti.
Aggiornato 29 set 2026  · 8 min leggi

Scopri con l'IA

ChatGPTClaudePerplexity

Ti sei mai chiesto come fa Python a far funzionare senza intoppi le tue classi personalizzate con le funzioni integrate? Il merito va a quei pratici metodi "dunder" — abbreviazione di double underscore methods.

Immagina di creare una classe per i numeri complessi e voler usare l'operatore + in modo naturale. Invece di scrivere codice extra per gestire l'addizione, definisci un metodo __add__ e Python si occupa del resto.

Questi metodi magici, come __init__ per la creazione dell'oggetto e __str__ per la rappresentazione testuale, vengono invocati automaticamente da Python, così non devi chiamarli direttamente. Evitano conflitti di nomi con i tuoi metodi normali e alimentano funzionalità come il sovraccarico degli operatori e i comportamenti personalizzati.

Che tu stia istanziando oggetti, eseguendo operazioni aritmetiche o semplicemente stampando un oggetto, i metodi dunder lavorano silenziosamente in background per rendere il tuo codice più elegante ed efficiente. Se sei alle prime armi con Python e vuoi recuperare alcune idee principali, segui il nostro corso Introduction to Python per una solida base.

Cosa sono i metodi Dunder in Python?

Come accennavo, i metodi dunder di Python sono metodi unici, o "magici", che costituiscono l'ossatura del modello dei dati di Python permettendo alle tue classi personalizzate di integrarsi con le operazioni integrate del linguaggio. Questi operatori includono azioni come la stampa, il confronto e le operazioni aritmetiche.

Quando definisci metodi come __init__ per inizializzare gli oggetti, __repr__ e __str__ per la loro rappresentazione, o anche __del__ per la pulizia, stai essenzialmente dicendo a Python come gestire le operazioni standard sui tuoi oggetti. L'interprete chiama automaticamente questi metodi quando viene eseguita l'operazione corrispondente. Questa automazione integrata crea un ponte tra le funzionalità native di Python e le classi definite dall'utente.

Più avanti vedremo esempi di classi che usano questi metodi e di classi che non li usano, così potrai capire come funziona tutto questo.

Categorie di metodi Dunder

Esploriamo le principali categorie di metodi dunder e vediamo come potenziano il tuo codice.

1. Inizializzazione e costruzione

Metodi dunder come __new__, __init__ e __del__ controllano come gli oggetti vengono creati, inizializzati e infine distrutti.

  • __new__ vs. __init__: __new__ è responsabile della creazione di una nuova istanza, mentre __init__ la inizializza. Questa separazione è importante quando si lavora con tipi immutabili, dove potresti sovrascrivere __new__ per altri scopi.

  • __del__: Questo metodo funge da distruttore, consentendo la pulizia quando un oggetto sta per essere raccolto dal garbage collector.

Puoi persino personalizzare __new__ nelle classi immutabili per imporre regole specifiche di creazione.

2. Metodi numerici e aritmetici

Metodi dunder come __add__, __sub__, __mul__ e le loro varianti in-place consentono ai tuoi oggetti di supportare le operazioni aritmetiche. Questo è noto come sovraccarico degli operatori. Definendo questi metodi, puoi abilitare un comportamento aritmetico naturale per i tuoi oggetti personalizzati.

Per esempio, sovraccarica __add__ in una classe Vector per sommare gli elementi corrispondenti di due vettori. Questo è particolarmente utile quando progetti classi che modellano concetti matematici o strumenti finanziari.

3. Metodi di confronto e uguaglianza

Metodi come __eq__, __lt__ e __gt__ determinano come vengono confrontati gli oggetti. Questi metodi ti permettono di definire cosa significa che due oggetti siano uguali o come debbano essere ordinati.

Un esempio tipico è il confronto delle aree di due figure: puoi sovrascrivere __lt__ per restituire true se l'area di una figura è minore di quella dell'altra. Questo può essere utile in collezioni o algoritmi di ordinamento.

4. Metodi di rappresentazione testuale

I metodi __str__ e __repr__ controllano come i tuoi oggetti vengono mostrati come stringhe.

  • __repr__ dovrebbe fornire una rappresentazione adatta agli sviluppatori che possa essere usata per ricreare l'oggetto.

  • __str__ punta a una visualizzazione adatta all'utente.

5. Metodi per contenitori e iterabili

Per far sì che i tuoi oggetti si comportino come sequenze o contenitori, puoi implementare metodi come __len__, __getitem__ e __iter__. Questo abilita operazioni come indicizzazione, iterazione e test di appartenenza.

Per esempio, se progetti uno stack o una lista personalizzata, implementando questi metodi puoi usare funzioni integrate come len().

6. Chiamabilità e programmazione funzionale

Con il metodo __call__, le istanze della tua classe possono essere invocate come funzioni. Questo è particolarmente utile per creare oggetti funzione con stato che possano memorizzare risultati o mantenere uno stato interno tra le chiamate. Pensalo come trasformare il tuo oggetto in un mini motore di calcolo che puoi chiamare ripetutamente con parametri diversi.

7. Gestori di contesto

Implementando i metodi __enter__ e __exit__ i tuoi oggetti possono essere usati con l'istruzione with per la gestione delle risorse. Questo è fondamentale per gestire risorse come handle di file o connessioni di rete, assicurando che siano configurate e liberate correttamente.

Uno scenario reale è usare un context manager personalizzato per aprire e chiudere in sicurezza le connessioni al database.

8. Accesso agli attributi e descriptor

Metodi come __getattr__, __setattr__ e __delattr__ ti permettono di controllare come gli attributi vengono accessi e modificati. Il protocollo dei descriptor affina ulteriormente questo aspetto permettendo agli oggetti di gestire dinamicamente l'accesso agli attributi.

Per esempio, un descriptor può convalidare o trasformare i valori degli attributi, assicurandosi che rispettino criteri specifici prima di essere impostati.

Metodi Dunder avanzati e vari  

Sebbene i metodi dunder principali coprano la maggior parte dei casi d'uso, Python include metodi avanzati e specializzati per attività come la programmazione asincrona, la metaprogrammazione e i comportamenti specifici delle librerie. Per esempio:  

  • Metodi asincroni: Metodi come __aiter__ e __anext__ abilitano l'iterazione asincrona, mentre __await__ supporta oggetti awaitable.  

  • Hook di metaprogrammazione: Metodi come __prepare__ e __set_name__ consentono la creazione dinamica delle classi e l'assegnazione dei nomi agli attributi.  

  • Metodi specifici delle librerie: Librerie come NumPy o Pandas spesso definiscono metodi dunder personalizzati (ad es., __array__ per l'integrazione con NumPy).

Questi metodi avanzati sono in genere usati per compiti specializzati, quindi la maggior parte degli sviluppatori non ne avrà bisogno ogni giorno. Tuttavia, mostrano la flessibilità e la profondità di Python. Ti consiglio di esplorare la documentazione ufficiale del modello dei dati di Python per un elenco completo. Questa risorsa fornisce dettagli completi su tutti i metodi dunder e sul loro utilizzo previsto.

Tutti i metodi Dunder in Python

Python fornisce oltre 100 metodi dunder, ciascuno progettato per controllare diversi aspetti del comportamento degli oggetti. Anche se in questo articolo abbiamo esplorato le categorie principali, ecco un riepilogo di alto livello che funge da riferimento rapido:

  • Metodi aritmetici: Metodi come __add__, __sub__, __mul__ e __truediv__ consentono ai tuoi oggetti di supportare gli operatori (+, -, *, /).

  • Metodi di confronto: Metodi come __eq__, __lt__ e __gt__ definiscono come gli oggetti vengono confrontati per uguaglianza o ordine.

  • Gestione degli attributi: Con metodi come __getattr__, __setattr__ e __delattr__ puoi controllare l'accesso agli attributi e implementare comportamenti dinamici.

  • Inizializzazione e costruzione: __new__, __init__ e __del__ gestiscono rispettivamente la creazione, l'inizializzazione e la pulizia degli oggetti.

  • Rappresentazione testuale: Metodi come __str__ e __repr__ determinano come gli oggetti sono rappresentati come stringhe, favorendo un output leggibile.

  • Iterazione e comportamento da contenitore: Implementa __iter__ e __next__ per rendere i tuoi oggetti iterabili e altri metodi per supportare indicizzazione e recupero della lunghezza.

  • Chiamabilità: __call__ consente a un'istanza di essere chiamata come una funzione, abilitando uno stile di programmazione funzionale con comportamento stateful.

  • Gestione del contesto: Con __enter__ e __exit__, gli oggetti possono essere usati con le istruzioni with per gestire correttamente le risorse.

  • Hook di metaprogrammazione: Metodi come __init_subclass__ offrono modi per personalizzare dinamicamente la creazione e il comportamento delle classi.

Fai riferimento alla documentazione ufficiale del modello dei dati di Python per un elenco completo e dettagliato di questi metodi dunder e delle loro funzionalità. Questa risorsa completa ti aiuterà a sbloccare tutta la potenza del modello a oggetti di Python e a scrivere codice più elegante ed efficiente.

Esempi reali e casi d'uso

Vediamo come i metodi dunder possono alimentare scenari reali attraverso alcuni esempi.

Sovraccarico degli operatori

Immagina di avere una classe numerica o testuale personalizzata. Implementando metodi dunder come __add__ o __mul__, permetti ai tuoi oggetti di funzionare in modo naturale con gli operatori aritmetici. Puoi sommare, sottrarre o moltiplicare istanze proprio come faresti con i tipi integrati, facendo sì che le tue classi personalizzate si integrino senza soluzione di continuità con le operazioni aritmetiche di Python.

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})"

# Usage
v1 = Vector(1, 2)
v2 = Vector(3, 4)

result = v1 + v2
print(result)  # Output: Vector(4, 6)

Caching con la chiamabilità

Hai mai voluto evitare di ripetere calcoli costosi? Implementando il metodo __call__, puoi far comportare un oggetto come una funzione che memorizza in cache i suoi risultati. Questo ti permette di salvare l'esito di un calcolo oneroso e restituirlo rapidamente alle chiamate successive, ottimizzando le prestazioni e risparmiando tempo di elaborazione prezioso.

class CachedComputation:
   def __init__(self):
        self.cache = {}
   def __call__(self, x):
        if x not in self.cache:
            self.cache[x] = self._expensive_computation(x)
        return self.cache[x]
   def _expensive_computation(self, x):
        # Imagine a complex calculation here
        return x ** 2

# Usage
compute = CachedComputation()

print(compute(5))  # Computes and caches: Output: 25
print(compute(5))  # Retrieves from cache: Output: 25

Context manager personalizzati

Creare un context manager usando i metodi __enter__ e __exit__ ti consente di automatizzare la gestione delle risorse. Per esempio, puoi progettare un context manager personalizzato per gestire le operazioni sui file — aprendo un file quando entri in un blocco e assicurandoti che venga chiuso quando esci. Questo semplifica il codice e previene errori comuni come le perdite di risorse.

class FileHandler:
   def __init__(self, filename, mode):
        self.filename = filename
        self.mode = mode
   def __enter__(self):
        self.file = open(self.filename, self.mode)
        return self.file
   def __exit__(self, exc_type, exc_val, exc_tb):
        self.file.close()

# Usage
with FileHandler("example.txt", "r") as file:
    content = file.read()
    print(content)

Iterabili e contenitori personalizzati

Per far funzionare i tuoi contenitori personalizzati con i cicli e le comprehension di Python, implementa il protocollo di iterazione definendo metodi come __iter__ e __next__. Che tu stia costruendo uno stack, una coda o qualsiasi altro contenitore personalizzato, questi metodi permettono di iterare sui tuoi oggetti proprio come su una lista normale, aumentando la flessibilità e l'usabilità delle tue classi.

class Stack:
   def __init__(self):
        self.items = []
   def push(self, item):
	self.items.append(item)
   def pop(self):
        return self.items.pop()
   def __iter__(self):
        self.index = 0
        return self
   def __next__(self):
        if self.index >= len(self.items):
            raise StopIteration
        item = self.items[self.index]
        self.index += 1
        return item

# Usage
stack = Stack()
stack.push(1)
stack.push(2)
stack.push(3)

for item in stack:
    print(item)  # Output: 1, 2, 3

Per approfondire gli iterabili personalizzati e il comportamento dei contenitori, dai un'occhiata al Python Lists Tutorial e a Python List Functions & Methods Tutorial and Examples.

Best practice con i metodi Dunder

Quando e come sovrascrivere i metodi dunder è fondamentale. Ecco alcune linee guida da tenere a mente:

Quando sovrascrivere

Sovrascrivi i metodi dunder solo se devi personalizzare il comportamento. Per esempio, se vuoi che i tuoi oggetti supportino operazioni aritmetiche o controlli di uguaglianza in un modo specifico, allora vale la pena implementare metodi come __add__ o __eq__.

Coerenza

Se sovrascrivi un metodo, come __eq__ per i controlli di uguaglianza, aggiorna di conseguenza i metodi correlati come __hash__. Questa coerenza assicura che i tuoi oggetti si comportino correttamente in collezioni come set o dizionari.

Evita l'abuso

Resisti alla tentazione di creare nuovi nomi dunder al di fuori del modello di dati standard di Python. Attenersi all'insieme integrato di metodi dunder mantiene il tuo codice chiaro e previene comportamenti inattesi.

Considerazioni sulle prestazioni

Tieni presente che sovrascrivere eccessivamente i metodi dunder, specialmente nelle parti del codice eseguite più spesso, può impattare sulle prestazioni. Punta a implementazioni efficienti per evitare rallentamenti nelle operazioni ad alta frequenza.

Conclusione e risorse aggiuntive

I metodi dunder permettono alle tue classi Python di interagire senza attriti con le funzionalità integrate del linguaggio, rendendo il tuo codice più pulito e intuitivo. Consentono ai tuoi oggetti di gestire tutto, dall'aritmetica e i confronti fino alla gestione personalizzata degli attributi, senza sforzo aggiuntivo da parte tua. Dovresti sperimentare questi metodi nei tuoi progetti e vedere come possono semplificare operazioni complesse.

Per approfondimenti, consulta la documentazione ufficiale del modello dei dati di Python. Troverai utili anche le nostre risorse DataCamp:


Oluseye Jeremiah's photo
Author
Oluseye Jeremiah
LinkedIn

Technical writer specializzato in AI, ML e data science: rende idee complesse chiare e accessibili.

Argomenti
Python

Impara Python con DataCamp

Corso

Python - Livello Intermedio

4 ore
1.4M
Migliora le tue competenze nella scienza dei dati creando visualizzazioni con Matplotlib e manipolando DataFrames con pandas.
Vedi i dettagliRight Arrow
Inizia Il Corso
Mostra altroRight Arrow
Correlato

blog

Tokenizzazione nel NLP: come funziona, sfide e casi d'uso

Guida al preprocessing NLP nel machine learning. Copriamo spaCy, i transformer di Hugging Face e come funziona la tokenizzazione in casi d'uso reali.
Abid Ali Awan's photo

Abid Ali Awan

10 min

blog

I 15 migliori server MCP remoti che ogni AI builder dovrebbe conoscere nel 2026

Scopri i 15 migliori server MCP remoti che stanno trasformando lo sviluppo AI nel 2026. Scopri come migliorano automazione, ragionamento, sicurezza e velocità dei workflow.
Abid Ali Awan's photo

Abid Ali Awan

15 min

blog

Che cos'è Snowflake? Guida per principianti alla piattaforma dati cloud

Esplora le basi di Snowflake, la piattaforma dati cloud. Scopri la sua architettura, le sue funzionalità e come integrarla nelle tue pipeline di dati.
Tim Lu's photo

Tim Lu

12 min

Mostra AltroMostra Altro