lettura facile

Il metodo __delete__() in Python

In questa lezione parliamo del metodo `__delete__()` dei descrittori in Python.

Che cos'è `__delete__()`? Immagina questo metodo come il "custode" di un attributo in un oggetto. Quando vuoi eliminare un attributo di un oggetto, puoi usare `__delete__()` per fare qualcosa in più. Ad esempio, puoi usarlo per fare dei controlli prima di cancellare l'attributo. Per utilizzarlo devi però gestire l'attributo tramite una classe descrittore.

Prima di parlare nello specifico di `__delete__()`, dobbiamo capire cosa sono i descrittori (o descriptor).

I descrittori sono oggetti che gestiscono l'accesso ad altri attributi di un oggetto. Sono classi che implementano almeno uno di questi metodi:

  • `__get__()`: Viene chiamato quando leggi l'attributo.
  • `__set__()`: Viene chiamato quando assegni un valore all'attributo.
  • `__delete__()`: Viene chiamato quando elimini l'attributo.

Quindi, `__delete__()` è un metodo speciale che ti permette di definire il comportamento dell'attributo quando viene cancellato.

__delete__(self, instance)

Dove:

  • `self` è un riferimento all'istanza del descrittore.
  • `instance` è l'istanza della classe che contiene l'attributo. 

A cosa serve? Il metodo `__delete__()` è come un "interruttore finale" per gli attributi speciali gestiti da un descrittore. Ti permette di definire cosa deve succedere quando quell'attributo viene cancellato. È uno strumento molto potente quando vuoi avere un controllo completo sul ciclo di vita degli attributi in un oggetto, rendendo il tuo codice più sicuro e prevedibile.

Vediamolo in azione con un esempio!

Un esempio pratico

Supponi di avere una classe che rappresenta un utente con un attributo `username`.

In questo caso, è opportuno che il nome utente non possa mai essere eliminato una volta impostato. Puoi farlo usando il metodo `__delete__()`.

Per prima cosa crea una classe descrittore chiamata 'NonCancellabile'.

class NonCancellabile:
    def __init__(self, valore):
        self._valore = valore

    def __get__(self, instance, owner):
        return self._valore

    def __set__(self, instance, value):
        self._valore = value

    def __delete__(self, instance):
        print("Errore: Non puoi cancellare questo attributo!")

Questa classe implementa alcuni tre metodi oltre al costruttore:

  • I metodi `__get__()` e `__set__() non svolgono alcuna azione aggiuntiva. Questo significa che è possibile leggere e modificare l'attributo.
  • Il metodo `__delete__()`, invece di eliminare l'attributo, stampa un messaggio di errore.

Ora crea la classe 'Utente' e definisci l'attributo 'username' tramite la classe descrittore 'NonCancellabile' che hai appena definito.

class Utente:
    username = NonCancellabile("user1")

    def __init__(self, password):
        self.password = password

Nota che la classe 'Utente' ha due attributi: 'username' e 'password'. Tuttavia, solo l'attributo 'username' viene gestito tramite il descrittore.

A questo punto genera un'istanza della classe 'Utente'.

utente = Utente('1234567')

Tra le parentesi tonde indica la password '1234567' che vuoi assegnare all'utente.

Il nome dell'utente 'user1' viene, invece, definito direttamente dal codice nell'attributo 'username'.

Se richiami l'attributo 'username' dell'oggetto, il valore assegnato viene stampato sullo schermo.

print(f"Username: {utente.username}")

Username: user1

Adesso, prova a cancellare l'attributo 'username' tramite l'istruzione del.

del utente.username

Quando tenti di cancellare l'attributo, Python chiama il metodo `__delete__()` del descrittore che  stampa un messaggio di errore e non esegue l'eliminazione dell'attributo.

Errore: Non puoi cancellare questo attributo!

Quindi, anche dopo aver chiamato `del utente.username`, l'attributo `username` rimane invariato.

Il codice `print(f"Username: {utente.username}")` mostrerà ancora l'username iniziale.

print(f"Username: {utente.username}")

Username: user1

In questo esempio, hai usato `__delete__()` per impedire che un attributo importante (in questo caso, `username`) venisse cancellato.

Perché usare `__delete__()`?

Il metodo `__delete__()` ti offre un controllo aggiuntivo su cosa accade quando un attributo viene eliminato.

È particolarmente utile quando vuoi garantire che la cancellazione avvenga in modo controllato, soprattutto in casi come la gestione di risorse (connessioni di rete, file aperti) o dati sensibili, dove una semplice rimozione potrebbe non essere sufficiente.

Può anche servire a proteggere dati critici all'interno di una classe, assicurandoti che non possano essere accidentalmente rimossi.

Come sempre, la semplicità è fondamentale: usa `__delete__()` solo quando aggiunge valore al comportamento della tua classe.

 




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




FacebookTwitterLinkedinLinkedin