lettura facile

Il parametro self in una classe in Python

Il parametro `self` rappresenta l'istanza della classe corrente in Python e puoi usarlo per accedere a variabili che appartengono alla classe.

In altre parole il parametro self è come un promemoria che aiuta a tenere traccia di quale specifico oggetto (istanza) sta operando all'interno della classe.

Perché usiamo `self`?

Il parametro`Self` è utile per permettere ai metodi di interagire con altri metodi e attributi della stessa istanza.

Lo usiamo per distinguere tra gli attributi/metodi interni della classe e le variabili locali nei metodi.

A cosa serve? Il parametro `self` è fondamentale per la programmazione orientata agli oggetti in Python, poiché permette alle classi di operare con i propri dati e comportamenti in modo organizzato. Grazie a `self`, ogni istanza mantiene il proprio stato e comportamento indipendentemente dalle altre istanze.

Per comprendere meglio, consideriamo un esempio pratico.

Immaginiamo di voler creare una classe per un libro. Un libro ha un titolo, un autore e può essere letto. Vediamo come potremmo strutturare questa classe:

class Libro:
    def __init__(self, titolo, autore):
       self.titolo = titolo
       self.autore = autore

    def mostra_informazioni(self):
       print(f"Titolo: {self.titolo}, Autore: {self.autore}")

In questo esempio la classe `Libro` viene definita con il metodo `__init__`, che è il costruttore della classe.

Gli attributi `titolo` e `autore` sono preceduti da `self`, il che significa che questi attributi sono specifici per l'oggetto creato.

Quindi, in questo caso il parametro `self` qui si riferisce all'oggetto `Libro` che viene creato.

Il metodo mostra_informazioni() utilizza `self` per accedere agli attributi dell'oggetto. In questo modo può lavorare con i dati specifici dell'oggetto su cui viene chiamato il metodo.

Ad esempio, crea alcuni oggetti della classe `Libro`:

libro1 = Libro("Il Piccolo Principe", "Antoine de Saint-Exupéry")
libro2 = Libro("Fondazione", "Isaac Asimov")

Quando crei un nuovo oggetto, Python automaticamente passa il riferimento dell'oggetto stesso al parametro self dei suoi metodi.

Ora puoi utilizzare i metodi per accedere alle informazioni contenute in ciascun oggetto.

Quando chiami il metodo mostra_informazioni() sull'oggetto libro1, ti restituisce il titolo e l'autore del libro.

libro1.mostra_informazioni()

Titolo: Il Piccolo Principe, Autore: Antoine de Saint-Exupéry

Lo stesso avviene quando chiami il metodo sull'oggetto libro2.

libro2.mostra_informazioni()

Titolo: Fondazione, Autore: Isaac Asimov

Quindi, ogni volta che chiami un metodo come `mostra_informazioni` su `libro1`, `self` in quel metodo si riferisce a `libro1`.

Quando, invece, chiami `leggi` su `libro2`, `self` si riferisce a `libro2`.

Cosa accade se non utilizzi self?

Se non utilizzi `self` quando definisci attributi o metodi all'interno di una classe in Python, finirai per avere comportamenti diversi, e in molti casi, risultati indesiderati.

Ad esempio, supponiamo di definire una classe senza usare `self` per gli attributi:

class Libro:
    def __init__(self, titolo, autore):
        titolo = titolo
        autore = autore

    def mostra_informazioni(self):
       print(f"Titolo: {titolo}, Autore: {autore}")

libro1 = Libro("Il Piccolo Principe", "Antoine de Saint-Exupéry")
libro2 = Libro("Fondazione", "Isaac Asimov")

libro1.mostra_informazioni()

In questo esempio, `titolo` e `autore` sono trattati come variabili locali all'interno del costruttore `__init__`.

Queste variabili sono disponibili solo durante l'esecuzione di `__init__` e non sono memorizzate come attributi dell'oggetto.

Di conseguenza, quando tenti di accedere a queste variabili nel metodo `mostra_informazioni`, Python solleva un'eccezione `NameError` perché `titolo` e `autore` non sono riconosciuti al di fuori di `__init__`.

NameError: name 'titolo' is not defined

Ora vediamo cosa accade se definisci un metodo senza usare `self`.

class Libro:
    def __init__(self, titolo, autore):
       self.titolo = titolo
       self.autore = autore

    def mostra_informazioni():
       print("Questo è un libro.")

libro1 = Libro("Il Piccolo Principe", "Antoine de Saint-Exupéry")
libro2 = Libro("Fondazione", "Isaac Asimov")

libro1.mostra_informazioni()

In questo caso il metodo non sarà legato all'istanza dell'oggetto:

Questo vuol dire che non potrai chiamarlo sull'istanza dell'oggetto perché Python si aspetta che il primo parametro di un metodo di istanza sia sempre una referenza all'oggetto stesso (tipicamente `self`).

Se provi a chiamare `mostra_informazioni` su un'istanza della classe `Libro`, otterrai un `TypeError`.

TypeError: Libro.mostra_informazioni() takes 0 positional arguments but 1 was given

Questo accade perché Python tenta di passare automaticamente l'oggetto istanza come primo argomento, e il metodo non è configurato per accettarlo.

Quindi, l'uso di `self` è essenziale per definire attributi e metodi che operano con le istanze specifiche di una classe.

Omettere `self` può portare a errori che impediscono il corretto funzionamento della classe, poiché le variabili locali saranno inaccessibili fuori dai loro metodi di definizione, e i metodi che non accettano `self` non potranno interagire con gli attributi dell'istanza.




Se qualcosa non ti è chiaro, scrivi la tua domanda nei commenti.




FacebookTwitterLinkedinLinkedin