Classi e Oggetti
- #python
- #programmazione
- #oop
- #classi
- #oggetti
In questa lezione
1. Introduzione
La programmazione orientata agli oggetti (OOP, Object-Oriented Programming) è un paradigma che organizza il codice attorno a oggetti, che combinano dati (attributi) e funzionalità (metodi).
Questo permette di “modellare” il mondo esterno in codice, rendendo il codice riusabile, organizzato e maggiormente manutenibile.
Python è un linguaggio fortemente orientato agli oggetti: tutto è un oggetto, anche numeri, stringhe, funzioni e moduli.
Classi e oggetti:
- Classe: È una sorta di template che serve per creare oggetti.
- Oggetto: È una specifica istanza di una classe.
Nota
Quindi, in altri termini, un oggetto è un’istanza concreta di una classe. La classe è come un modello o progetto da cui vengono creati gli oggetti.

L’OOP consente di:
- organizzare il codice in modo modulare e riutilizzabile;
- rappresentare entità reali (es. persona, automobile, studente) come oggetti nel programma;
- mantenere il codice più leggibile e scalabile.
2. Creazione di una Classe
Una classe in Python si definisce con la parola chiave class.
All’interno si possono definire attributi (dati) e metodi (funzioni).
class Persona:
pass
Questa classe è vuota, ma può essere utilizzata per creare oggetti:
p1 = Persona()
print(type(p1))
Output:
<class '__main__.Persona'>
In questo caso, p1 è un’istanza della classe Persona.
3. Il Metodo init (Costruttore)
Il metodo speciale __init__ è il costruttore: viene eseguito automaticamente alla creazione dell’oggetto.
Serve per inizializzare gli attributi di istanza, cioè i dati che appartengono a ciascun oggetto.

class Persona:
def __init__(self, nome, eta):
self.nome = nome
self.eta = eta
Creazione di un oggetto:
p1 = Persona("Anna", 25)
print(p1.nome)
print(p1.eta)
Nota
self rappresenta l’istanza corrente. È obbligatorio come primo parametro nei metodi della classe.
4. Attributi di Classe e di Istanza
- Attributi di istanza (instance variable): appartengono a una singola istanza (oggetto).
- Attributi di classe (class variable): condivisi da tutte le istanze della classe.
Esempio:
class Studente:
scuola = "Liceo Galileo" # attributo di classe
def __init__(self, nome, voto):
self.nome = nome # attributo di istanza
self.voto = voto
Uso:
s1 = Studente("Luca", 8)
s2 = Studente("Giulia", 9)
print(s1.scuola) # accesso all'attributo di classe
print(s2.voto) # accesso all'attributo di istanza
Suggerimento
Se si cambia Studente.scuola, la modifica sarà visibile in tutte le istanze.
Se invece si cambia s1.scuola, si crea un attributo solo per quell’oggetto.
5. Metodi
I metodi sono funzioni definite all’interno della classe. Servono per manipolare o mostrare i dati dell’oggetto.
class Persona:
def __init__(self, nome, eta):
self.nome = nome
self.eta = eta
def saluta(self):
print(f"Ciao, mi chiamo {self.nome} e ho {self.eta} anni.")
Uso:
p1 = Persona("Marco", 30)
p1.saluta()
Output: Ciao, mi chiamo Marco e ho 30 anni.
6. Metodi Speciali (Dunder Methods)
Python include molti metodi speciali (detti anche dunder methods, “double underscore”), che permettono di personalizzare il comportamento degli oggetti.
I più comuni:
| Metodo | Scopo |
|---|---|
__init__ | Inizializza l’oggetto alla creazione |
__str__ | Rappresentazione testuale leggibile |
__repr__ | Rappresentazione ufficiale (debug) |
__len__ | Lunghezza oggetto (usato da len()) |
__add__ | Somma tra oggetti personalizzata |
Esempio __str__:
class Punto:
def __init__(self, x, y):
self.x = x
self.y = y
def __str__(self):
return f"Punto({self.x}, {self.y})"
p = Punto(2, 5)
print(p) # usa automaticamente __str__
Output: Punto(2, 5)
7. Incapsulamento
L’incapsulamento serve a proteggere i dati interni all’oggetto, nascondendoli o limitandone l’accesso diretto.
In Python, gli attributi privati si dichiarano anteponendo un underscore _ (convenzione) o doppio underscore __ (name mangling).
Nota
Un singolo underscore _attributo è solo una convenzione: indica che l’attributo non dovrebbe essere usato all’esterno della classe, ma è comunque accessibile.
Il doppio underscore __attributo attiva il name mangling, cioè Python rinomina automaticamente l’attributo in _NomeClasse__attributo, rendendolo meno accessibile (ma non completamente privato).
class ContoBancario:
def __init__(self, titolare, saldo):
self.titolare = titolare
self.__saldo = saldo # attributo privato
def deposita(self, importo):
self.__saldo += importo
def preleva(self, importo):
if importo <= self.__saldo:
self.__saldo -= importo
else:
print("Saldo insufficiente.")
def mostra_saldo(self):
print(f"Saldo attuale: {self.__saldo} €")
Uso:
conto = ContoBancario("Luca", 1000)
conto.deposita(200)
conto.mostra_saldo()
conto.__saldo = 0 # non modifica il vero saldo
conto.mostra_saldo()
Attenzione
Gli attributi “privati” non sono veramente nascosti, ma resi meno accessibili (_ContoBancario__saldo). Python si basa sulla fiducia del programmatore, non su regole rigide.
8. Quiz a risposta multipla
Mettiti alla prova
0/10 risposte
1) In Python, cosa rappresenta una classe?
2) Che cos'è un oggetto in Python?
3) Qual è il ruolo del metodo __init__?
4) A cosa serve il parametro 'self' nei metodi di una classe?
5) Qual è la differenza tra attributo di classe e attributo di istanza?
6) Cosa fa il metodo __str__ in una classe?
7) Come si accede a un attributo privato in Python (solo per scopi di debug)?
8) Se si modifica un attributo di classe direttamente su un'istanza (es. s1.scuola = 'Nuovo Nome'), cosa accade?
9) Quale metodo speciale permette di personalizzare l'operatore + tra oggetti?
10) Cosa rappresenta l'incapsulamento nella programmazione a oggetti?
9. Esercizi
9.1 Esercizio - Rettangolo
Creare una classe Rettangolo che abbia:
- attributi
baseealtezza. - un metodo
area()che restituisce l’area, - un metodo
perimetro()che restituisce il perimetro, - un metodo
__str__()che descrive il rettangolo.