Python: dataclass, NamedTuple o dict? Quale scegliere (con misure)
2026-10-15
Quando devi passare in giro "un po' di campi", in Python hai tre scelte comuni: dict, NamedTuple e dataclass. Ecco le differenze, con numeri misurati su Python 3.12.15 (200.000 creazioni di un oggetto con due campi interi).
Il codice
from dataclasses import dataclass
from typing import NamedTuple
@dataclass
class PC:
x: int
y: int
@dataclass(slots=True) # Python 3.10+
class PD:
x: int
y: int
class PN(NamedTuple):
x: int
y: int
Risultati misurati
- dict: 12 ms, 184 byte
- NamedTuple: 33 ms, 56 byte
- dataclass: 23 ms, 136 byte (oggetto +
__dict__) - dataclass con slots: 21 ms, 48 byte
Il dict è il più veloce da creare ma il più pesante e senza controlli: un refuso nella chiave si scopre solo a runtime. Le misure dipendono dalla macchina; contano i rapporti, non i millisecondi assoluti.
Mutabilità e confronto
p = PC(1, 2); p.x = 5 # ok, la dataclass è mutabile
PN(1, 2).x = 5 # AttributeError: can't set attribute
PN(1, 2) == (1, 2) # True: la NamedTuple è una tupla
PC(1, 2) == (1, 2) # False
Il confronto con una tupla semplice può essere comodo o pericoloso: una NamedTuple di coordinate è uguale a qualunque tupla (1, 2), anche di tutt'altro significato.
Quale scegliere
- dataclass (di solito con
slots=True): la scelta di default per oggetti di dominio, con valori predefiniti, metodi efrozen=Truese vuoi l'immutabilità. - NamedTuple: record immutabili leggeri, utili se devi spacchettarli come tuple o usarli come chiavi di dizionario.
- dict: dati dinamici o provenienti da JSON, quando le chiavi non sono note in anticipo.
Se in dubbio, parti da @dataclass(slots=True): meno memoria, attributi controllati dall'editor e codice che si legge da solo.