01: Classi e Istanze - Programmare in Python

Video Corso Programmazione a Oggetti Python 3

01: Classi e Istanze

In questa nuova serie tratteremo alcune tematiche della Programmazione a Oggetti nel mondo di Python, partendo oggi da Classi e Istanze.

In questa lezione impararemo infatti come crearle e utilizzarle e qual'è la differenza tra le due.

Iniziamo rispondendo alla domanda più attesa: cosa sono le Classi e a Cosa ci servono?

Le classi sono un fantastico strumento che ci permette di raggruppare variabili e funzioni nei nostri programmi in maniera logica e riutilizzabile il che ci consente di gestire progetti anche di grosse dimensioni in maniera molto semplice.

Prestate attenzione, perché ora facciamo subito un esempio pratico.

Supponiamo di dover scrivere un'applicazione che gestisca l'aggiunta di Studenti al database di una Scuola. Ogni studente avrà attributi come Nome, Cognome e Corso di Studi seguito, più alcune funzioni associate che chiameremo metodi.

Ora, le scelte sono due: Nella nostra applicazione possiamo creare ciascuno studente singolarmente con tutte le sue proprietà e funzioni, il che chiederebbe tantissimo tempo, oppure trovare un modo per creare le varie entità studente in maniera rapida, un pó come quando la mamma o la nonna fanno i biscotti e usano gli stampini. Ricordiamo che ogni studente avrà almeno un nome, un cognome e un corso di studi.

In contesti come questo, usare le Classi risulta comodissimo perché ci permettono di modellare la realtà in maniera efficiente e come abbiamo detto riutilizzabile; grazie alle Classi possiamo definire le proprietà di ciascuno studente in un Modello Generico, proprio come per i biscotti, chiamato Classe e da qui far derivare ciascun singolo individuo assegnandoli i suoi attributi personali, vedremo a brevissimo come.

Una Classe viene spesso metaforizzata come una "fabbrica di oggetti", e ciascun oggetto creato a partire da questo Modello Generico viene chiamato Istanza.

Quindi una Classe non è altro che un sistema usato per modellare la realtà in modo da poter costruire e gestire oggetti più o meno complessi. Nel nostro esempio avremo quindis un Modello Generico di studente chiamato Classe Studente, ed Ogni studente creato sarà un'Istanza di questo Modello.

Direi che con la teoria e le metafore per ora puó bastare, passiamo al lato pratico. In Python, per creare una Classe studente ci basta fare:

class Studente:

Ora, possiamo iniziare ad aggiungere al nostro Modello Generico i vari attributi di uno Studente, abbiamo detto Nome, Cognome e Corso di Studi. Per aggiungere queste caratteristiche usiamo una funzione speciale, chiamata Metodo __init__, che significa inizializzatore, conosciuto anche come Metodo Costruttore. Il suo scopo nella "Fabbrica" è proprio quello di Costruire gli Oggetti: diciamo che fa buona parte del lavoro sporco per noi!

class Studente:
    def __init__(self):

Quando creiamo dei metodi all'interno della Classe, tra le parentesi di questi metodi passiamo, come primo parametro, l'Istanza della classe, e la chiamiamo per convenzione self, che in Italiano significa Se Stesso. Spiegheremo a brevissimo il perché di tutto questo, aggiungiamo prima il resto degli attributi:

class Studente:
    def __init__(self, nome, cognome, corso_di_studi):
        self.nome = nome
        self.cognome = cognome
        self.corso_di_studi = corso_di_studi

Ora, abbiamo detto che ai metodi viene passato self, quindi l'Istanza, perché rappresenta l'oggetto a cui dovranno essere associate il resto delle proprietà passate, Nome, Cognome ecc. Abbiamo detto che la Classe è un Modello Generico, e quindi deve essere valido per ogni Studente Creato, giusto? self rappresenta quindi una referenza a ciascun'oggetto creato dalla Classe, e il Metodo __init__ inizializza e attiva le varie proprietà di ciascun self, quindi di Ciascun Oggetto o Istanza.

Quindi per ciascuno dei self, ovvero degli Studenti inizializzati, il nome sarà corrispondente al Nome Passato ad __init__, il Cognome di ciascun self sarà corrispondente al Cognome Passato, e stesso discorso per il corso di Studi. Questi attributi prendono il nome di Variabili dell'Istanza.

Ci Siamo? Facciamo così, inizializziamo due Istanze passando alla nostra Fabbrica due set di dati così che ci vada a costruire due Entità Studente.

studente_uno = Studente("Py", "Mike", "programmazione")
studente_due = Studente("Marta", "Stannis", "scienze politiche")

Proviamo a passare a print() sia studente_uno che studente_due e vediamo cosa ci restituisce:

print(studente_uno)
print(studente_due)

<__main__.Studente object at 0x7f4fdfcd26d8><__main__.Studente object at 0x7f4fdfcd28d0>

Come vedete dall'output di print(), si tratta di Oggetti di tipo Studente, quindi creati dal nostro Modello Generico della Classe Studente, presenti in due allocazioni di Memoria diverse. Ciascuno con le sue proprietà, ciascuno con la sua zona di Memoria. Volendo, ora che il modello è stato progettato, potete creare centinaia di studenti a partire dalla stessa classe, in maniera estremamente semplice e conveniente!

Ora, portiamo il tutto un gradino più in alto, aggiungendo un secondo metodo alla nostra Classa, una funzione che ci permetta di visualizzare la scheda personale di ciascuno Studente. Dopotutto, si tratta di un'azione piuttosto comune in questi casi, giusto?

class Studente:
    def __init__(self, nome, cognome, corso_di_studi):
        self.nome = nome
        self.cognome = cognome
        self.corso_di_studi = corso_di_studi

    def scheda_personale(self):
        return f"Scheda Studente\n Nome:{self.nome}\n Cognome:{self.cognome}\n Corso Di Studi:{self.corso_di_studi}"

Come abbiamo detto in precedenza, ad ogni metodo della classe viene passato anzitutto self, quindi l'Istanza: E ogni attributo passato alla scheda va preceduto da self, quindi self.nome, self.cognome ecc, per fare in modo che il Metodo scheda_personale funzioni su ciascuna Istanza della Classe.

Ora possiamo richiamare questo metodo su qualsiasi Oggetto abbiamo creato:

print(studente_uno.scheda_personale())
print(studente_due.scheda_personale())

Scheda Studente
  Nome: Py
  Cognome: Mike
  Corso Di Studi: programmazione

Scheda Studente
  Nome: Marta
  Cognome: Stannis
  Corso Di Studi: scienze politiche

Prima di chiudere voglio farvi notare un'ultimo dettaglio che vi permetterà di chiarire ulteriormente il nesso tra Classe, Istanza e self. Oltre a chiamare i metodi della Classe sull'Istanza, come abbiamo appena fatto, possiamo chiamarli anche sulla Classe stessa:

print(Studente.scheda_personale(studente_uno))

Scheda Studente
  Nome: Py
  Cognome: Mike
  Corso Di Studi: programmazione

Come vedete i risultati sono identici a quelli ottenuti precedentemente, con la differenza che stavolta come parametro abbiamo dovuto passare il nome dell'Istanza per cui volevamo ottenere la scheda personale.

Di fatto, questo è ció che succede in maniera automatica quando chiamiamo il metodo su ciascun Oggetto, ed è proprio per questo motivo che utilizziamo self, che rappresenta quindi l'Istanza passata automaticamente!




Menu della Serie