lettura facile

I metodi in una classe Python

I metodi di una classe sono funzioni che definiscono il comportamento degli oggetti creati con la classe o della classe stessa.

Cos'è una classe? In Python, una classe può essere vista come un modo per creare oggetti che condividono le stesse proprietà e comportamenti. 

In Python, gli attributi di una classe possono essere generalmente divisi in due grandi categorie: metodi e proprietà.

  • Metodi (attributi chiamabili)
    Sono funzioni definite all'interno di una classe e, come hai detto, sono "chiamabili". Ciò significa che possono essere invocati o eseguiti, poiché sono funzioni. Operano sui dati dell'oggetto e possono anche manipolare lo stato della classe o dell'istanza.
  • Proprietà (attributi non chiamabili)
    Questi sono gli attributi non chiamabili che contengono dati o informazioni. Sono spesso definiti nel metodo __init__ di una classe e possono essere utilizzati per mantenere lo stato dell'oggetto. Esempi comuni di proprietà possono essere nome, marca, modello ecc., in una classe che rappresenta un prodotto o un veicolo.

In generale puoi vedere i metodi come attributi chiamabili della classe.

In realtà Python ammette anche una terza categoria intermedia detta delle "proprietà chiamabili" che ti permette di trattare i metodi come attributi non chiamabili. Ma di questo ne parleremo in una lezione a parte.

Il linguaggio Python ammette diversi tipi di metodi: di istanza, di classe e statici.

I metodi di istanza e di classe sono legati rispettivamente all'istanza o alla classe e sono detti "bound methods".

Viceversa, i metodi statici non hanno un riferimento né all'istanza, né alla classe.

Metodi di istanza

I metodi di istanza operano sui dati di un singolo oggetto creato dalla classe.

Questi metodi hanno bisogno di un riferimento all'oggetto stesso (`self`) per manipolare i dati dell'oggetto.

class Automobile:
    def __init__(self, marca, modello):
        self.marca = marca
        self.modello = modello
    def descrizione(self):
        return f"{self.marca} {self.modello}"

# Creazione di un'istanza
auto = Automobile("Fiat", "500")
print(auto.descrizione())

Fiat 500

In questo esempio, `descrizione` è un metodo di istanza.

Utilizza `self` per accedere alle proprietà dell'oggetto e restituire una stringa che descrive l'automobile.

Metodi di classe

I metodi di classe lavorano con la classe stessa piuttosto che con l'istanza.

Sono marcati con il decoratore `@classmethod` e prendono come primo parametro la classe, di solito chiamata `cls`.

class Automobile:
      tasso_tasse = 1.20
     @classmethod
     def tassa(cls, prezzo):
           return cls.tasso_tasse * prezzo

# Uso del metodo di classe
print(Automobile.tassa(15000)

18000

In questo caso, `tassa` è un metodo di classe che calcola le tasse basate su un tasso definito a livello di classe.

Puoi accedere a questo metodo direttamente dalla classe, senza creare un'istanza.

Metodi statici

I metodi statici sono simili ai metodi di classe ma non prendono automaticamente un riferimento né all'istanza (`self`) né alla classe (`cls`).

Sono utili per funzionalità che non necessitano di accedere agli attributi dell'oggetto o della classe.

Si marcano con `@staticmethod`.

class Automobile:
    @staticmethod
    def valida_targa(targa):
        return len(targa) == 7

# Uso del metodo statico
print(Automobile.valida_targa("1234567")

True

Questo metodo statico può essere chiamato per verificare se una targa ha il numero corretto di caratteri, indipendentemente da qualsiasi specifica istanza o classe.

Quando progetti una classe, pensa a quali operazioni sono strettamente collegate alle istanze (metodi di istanza), quali appartengono alla classe nel suo insieme (metodi di classe), e quali operazioni sono genericamente utili e non dipendono dall'istanza o dalla classe stessa (metodi statici). In questo modo puoi strutturare il codice in modo chiaro e logico, rendendo più facile la manutenzione e la comprensione del programma.

Le variabili locali nei metodi

Le variabili create all'interno dei metodi sono variabili locali a quei metodi.

Non sono accessibili né dall'esterno del metodo né da altre istanze/metodi, a meno che non vengano definiti come attributi di istanza o classe.

Questo significa che le variabili nei metodi esistono solo durante l'esecuzione del metodo e non sono visibili o accessibili fuori dal metodo stesso. Questo isolamento aiuta a mantenere i metodi indipendenti l'uno dall'altro e consente l'incapsulamento. L'incapsulamento è uno dei principi fondamentali della programmazione orientata agli oggetti, perché protegge lo stato interno di un oggetto (le sue variabili) dall'accesso diretto esterno ed espone solo ciò che è necessario tramite metodi pubblici.

Ad esempio, questo script contiene una classe e alcune variabili di diverso tipo.

class Car:
    message="welcome"  # Attributo di classe

    def __init__(self, color):
        self.color = color # Attributo di istanza
        self.message="hello"

    def display_info(self):
        message = f"This car is {self.color}." # Variabile locale
        return message

# Creazione di istanze della classe Car
car1 = Car("red")

message="welcome"  # variabile globale

In questo script ci sono ben quattro variabili con lo stesso nome "message": una variabile locale nel metodo, un attributo di istanza, un attributo di classe e una variabile globale.

Questo accade perché in Python, ci sono diversi "scope" o ambiti in cui le variabili possono esistere.

La variabile locale "message" è visibile solo quando chiami il metodo display_info(self) che la contiene.

print(car1.display_info()) 

This car is red.

Se invece digiti car1.message Python accede all'attributo di istanza "hello".

print(car1.message)

hello

Ricorda che quando un metodo tenta di accedere a variabili che non sono locali, prima cerca nelle variabili di istanza, quelle accessibili tramite self, poi nelle variabili di classe, e infine nelle variabili globali.

Se la variabile non viene trovata in nessuno di questi ambiti, Python solleva un NameError, indicando che la variabile non è stata definita.

Un errore comune per i principianti è tentare di accedere direttamente a una variabile di classe dentro un metodo senza qualificarla con il nome della classe o self (per le variabili di istanza). Questo porta a un NameError a meno che non ci sia una variabile locale o globale con lo stesso nome.




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




FacebookTwitterLinkedinLinkedin