lettura facile

Il decoratore @setter in Python

Il decoratore @setter in Python è usato per creare una interfaccia a un attributo privato di una classe.

@setter

Questo decoratore va usato in combinazione con il decoratore @property che trasforma un metodo in un attributo "getter".

In questo modo, ogni volta che cerchi di inizializzare o modificare un valore, viene richiamata un'interfaccia per controllare e validare i dati.

Si tratta di un argomento che può sembrare un po' criptico ma è in realtà molto utile per gestire come gli attributi di una classe vengono modificati, perché ti permette di modificare il comportamento di funzioni o metodi senza alterarne direttamente il codice.

Facciamo un esempio pratico.

Supponiamo di voler creare una classe `Circle` per rappresentare un cerchio in Python.

Vogliamo però assicurarci che il raggio non sia mai impostato su un valore negativo o nullo. Per gestire questo comportamento utilizzeremo @property e @setter. 

class Circle:
    def __init__(self, radius):
        self.radius = radius  # Utilizza il setter per impostare il raggio

    @property
    def radius(self):
        return self._radius

    @radius.setter
    def radius(self, value):
        if value <= 0:
            raise ValueError("Il raggio deve essere maggiore di zero.")
        self._radius = value

In questo codice il costruttore `__init__` imposta il raggio del cerchio tramite il metodo @radius.setter che effettua un controllo sul valore prima di assegnarlo all'attributo privato `_radius`.

Nota che l'uso di _radius invece di radius all'interno della classe Circle è una convenzione comune in Python che ha a che fare con l'incapsulamento, è utile per nascondere i dettagli interni della classe e esporre solo quelle parti che sono necessarie per l'interfaccia esterna.

Se il valore è zero o negativo, viene sollevata un'eccezione.

Ad esempio, prova ad assegnare -5 al raggio.

Il costruttore passa -5 al metodo setter 'radius' che rileva un numero negativo e solleva un'eccezione.

circle = Circle(-5)

ValueError: Il raggio deve essere maggiore di zero.

L'utilizzo di `@property` e `@setter` in questo contesto ti garantisce che il raggio del cerchio sia sempre positivo.

Questo approccio ti consente di raggiungere almeno tre risultati:

  • Incapsulamento: Le proprietà della classe sono protette da assegnazioni errate.
  • Validazione dei dati: Puoi definire un criterio di validazione dei dati quando un attributo viene modificato.
  • Interfaccia: L'uso esterno della classe rimane pulito e semplice, poiché si può accedere agli attributi direttamente.

Questi strumenti, quando usati correttamente, non solo rendono il codice più sicuro ma anche più facile da leggere e mantenere.

La chiave è capire quando e come usarli per sfruttare al meglio i loro vantaggi.

Nota che in Python l'uso del decoratore @setter è strettamente legato al decoratore @property, e non può essere usato da solo.

  • Il decoratore @property viene usato per definire un metodo getter che accede a un attributo di una classe. Il metodo diventa così un attributo "pseudo" della classe, accessibile senza parentesi come se fosse un attributo normale e non un metodo.
  • Il decoratore @setter è usato per definire il metodo setter corrispondente a un metodo getter definito tramite @property. Questo setter consente di modificare il valore dell'attributo, implementando eventuali controlli o validazioni necessarie.
    Perché non si può usare @setter da solo

Quindi, il decoratore @setter è tecnicamente parte dell'infrastruttura creata dal decoratore @property. Quando definisci un @setter, lo fai come una seconda definizione del metodo con lo stesso nome del metodo @property, ma decorato con @nome_proprietà.setter. Se tentassi di usare @setter senza aver prima definito la proprietà con @property, Python non saprebbe a quale proprietà si riferisce il setter, causando un errore di sintassi.




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




FacebookTwitterLinkedinLinkedin