Introduzione
Quando si parla di programmazione a oggetti in Python, spesso l’attenzione si concentra subito su classi, costruttori ed ereditarietà. Tuttavia, uno degli aspetti più utili e pratici per lavorare davvero bene con gli oggetti è capire come funzionano i metodi di istanza.
I metodi di istanza sono funzioni definite dentro una classe che operano su un singolo oggetto alla volta. Sono il modo più naturale per far “comportare” un oggetto: aggiornare i suoi dati, calcolare valori derivati, validare input e offrire un’interfaccia chiara a chi usa la classe.
In questo tutorial vedremo come usare i metodi di istanza in modo corretto, come progettare classi più pulite e come evitare errori comuni. Useremo un esempio realistico: la gestione di un piccolo conto digitale.
Codice completo
class ContoDigitale:
def __init__(self, intestatario, saldo_iniziale=0):
self.intestatario = intestatario
self.saldo = saldo_iniziale
self.movimenti = []
def deposita(self, importo):
if importo <= 0:
raise ValueError("L´importo del deposito deve essere positivo.")
self.saldo += importo
self.movimenti.append(f"Deposito: +{importo}€")
def preleva(self, importo):
if importo <= 0:
raise ValueError("L´importo del prelievo deve essere positivo.")
if importo > self.saldo:
raise ValueError("Fondi insufficienti.")
self.saldo -= importo
self.movimenti.append(f"Prelievo: -{importo}€")
def trasferisci(self, altro_conto, importo):
if not isinstance(altro_conto, ContoDigitale):
raise TypeError("Il destinatario deve essere un oggetto ContoDigitale.")
self.preleva(importo)
altro_conto.deposita(importo)
self.movimenti.append(
f"Trasferimento a {altro_conto.intestatario}: -{importo}€"
)
altro_conto.movimenti.append(
f"Trasferimento da {self.intestatario}: +{importo}€"
)
def riepilogo(self):
print(f"Conto intestato a: {self.intestatario}")
print(f"Saldo attuale: {self.saldo}€")
print("Movimenti:")
for movimento in self.movimenti:
print("-", movimento)
# Creazione di due oggetti
conto_luca = ContoDigitale("Luca", 100)
conto_marta = ContoDigitale("Marta", 50)
# Uso dei metodi di istanza
conto_luca.deposita(25)
conto_luca.preleva(10)
conto_luca.trasferisci(conto_marta, 40)
# Visualizzazione dello stato finale
conto_luca.riepilogo()
print()
conto_marta.riepilogo() Spiegazione
La classe ContoDigitale rappresenta un conto semplice. Ogni oggetto creato da questa classe ha tre attributi di istanza:
- intestatario: il nome del proprietario del conto
- saldo: il denaro disponibile
- movimenti: la lista delle operazioni effettuate
Il metodo __init__ inizializza questi dati quando creiamo un nuovo oggetto. Subito dopo, i metodi di istanza ci permettono di interagire con lo stato interno del conto.
Il metodo deposita()
Questo metodo riceve un importo e lo somma al saldo. Prima controlla che il valore sia positivo. È una buona pratica fondamentale: non bisogna mai accettare dati incoerenti solo perché “funzionano” tecnicamente.
In più, il metodo registra l’operazione nella lista movimenti. Questo approccio è utile perché conserva una traccia delle azioni svolte sull’oggetto.
Il metodo preleva()
Qui vediamo un altro vantaggio dei metodi di istanza: il controllo della logica interna. Il metodo verifica che il prelievo sia positivo e che il saldo sia sufficiente. Se una condizione non è rispettata, solleva un’eccezione con un messaggio chiaro.
Questo rende la classe più robusta e impedisce di portarla in uno stato non valido.
Il metodo trasferisci()
Questo è un esempio molto interessante perché mostra come un oggetto possa collaborare con un altro oggetto della stessa classe. Il metodo:
- controlla che il destinatario sia davvero un ContoDigitale
- preleva l’importo dal conto corrente
- deposita l’importo nel conto destinazione
- registra il movimento su entrambi i conti
È un ottimo esempio di progettazione orientata agli oggetti: ogni oggetto conosce il proprio comportamento e interagisce con altri oggetti in modo controllato.
Il metodo riepilogo()
Questo metodo non modifica lo stato dell’oggetto, ma lo mostra in modo leggibile. È tipico avere metodi che servono a:
- esporre informazioni
- stampare report
- calcolare valori derivati
In un progetto reale, invece di usare print() dentro il metodo, spesso si preferisce restituire una stringa o una struttura dati. In questo esempio, però, la stampa diretta aiuta a capire il concetto in modo immediato.
Best practice
I metodi di istanza sono semplici da usare, ma ci sono alcune regole che rendono il codice più pulito e affidabile.
- Usa self in modo coerente: è il riferimento all’istanza corrente. Serve per leggere e modificare gli attributi dell’oggetto.
- Valida sempre gli input: controlla valori negativi, tipi sbagliati o dati mancanti prima di aggiornare lo stato.
- Evita metodi troppo lunghi: se un metodo fa troppe cose, dividilo in funzioni più piccole e leggibili.
- Non esporre direttamente la logica interna: meglio offrire metodi come deposita() o preleva() invece di modificare saldo dall’esterno.
- Usa eccezioni chiare: ValueError e TypeError sono spesso sufficienti per segnalare problemi di input.
- Progetta metodi con nomi descrittivi: deposita(), preleva() e trasferisci() sono immediati da capire.
Un errore comune è pensare che basti creare attributi pubblici per avere una classe “a oggetti”. In realtà, il valore della programmazione orientata agli oggetti sta proprio nel concentrare dati e comportamento nello stesso punto, con regole ben definite.
Un altro consiglio utile è non abusare della stampa dentro i metodi. In applicazioni più grandi, è preferibile separare la logica del dominio dalla presentazione, così il codice resta più facile da testare e riutilizzare.
Riepilogo
I metodi di istanza sono uno dei mattoni fondamentali della programmazione a oggetti in Python. Servono a definire il comportamento degli oggetti e a gestire il loro stato in modo sicuro e organizzato.
- Ogni metodo di istanza lavora su un singolo oggetto tramite self
- Permettono di modificare attributi, validare dati e coordinare operazioni tra oggetti
- Aiutano a scrivere classi più chiare, riutilizzabili e facili da mantenere
- Sono ideali per modellare entità reali come conti, utenti, ordini o prodotti
Se stai iniziando con la programmazione a oggetti, padroneggiare i metodi di istanza è un passaggio essenziale: ti aiuta a passare da “scrivere codice che funziona” a “progettare oggetti che fanno bene il loro lavoro”.
Approfondisci con risorse ufficiali
- Documentazione ufficiale Python - Classes: https://docs.python.org/3/tutorial/classes.html
- Documentazione ufficiale Python - Data model: https://docs.python.org/3/reference/datamodel.html
- PEP 8 - Style Guide for Python Code: https://peps.python.org/pep-0008/
- Documentazione ufficiale Python - Built-in Exceptions: https://docs.python.org/3/library/exceptions.html
Se vuoi fare un passo in più, prova a trasformare questo esempio in una piccola applicazione con menu testuale, oppure aggiungi metodi come chiudi_conto() o applica_commissione(). È un ottimo esercizio per allenarti a progettare classi più realistiche.
