
Il metodo __delattr__() in Python
Il metodo speciale `__delattr__()` in Python ti permette di elminare un attributo da un oggetto.
E' un concetto che spesso non è immediato per chi inizia a programmare, ma che può essere molto utile una volta compreso.
Innanzitutto, in Python ogni cosa è un oggetto, e ogni oggetto ha attributi (proprietà, metodi, ecc.).
Ad esempio, crea una classe come questa:
class Persona:
def __init__(self, nome, eta):
self.nome = nome
self.eta = eta
Puoi pensare a `nome` e `eta` come attributi dell'oggetto creato dalla classe `Persona`.
Genera un'istanza della classe ossia un oggetto.
p = Persona("Anna", 30)
Ora, normalmente puoi accedere a questi attributi e persino modificarli facilmente:
print(p.nome)
Anna
Puoi anche decidere di eliminare un attributo dell'oggetto usando l'istruzione `del`.
del p.nome
Quando usi `del p.nome`, Python chiama internamente `__delattr__(self, nome)`.
È un po’ come il corrispettivo del più noto `__getattr__()` per ottenere un attributo o `__setattr__()` per impostarlo.
Quindi, puoi ottenere lo stesso risultato anche chiamando il metodo `__delattr__()` dall'oggetto.
p.__delattr__('nome')
In entrambi i casi l'attributo 'nome' viene eliminato dall'oggetto 'p'.
print(p.nome)
AttributeError: 'Persona' object has no attribute 'nome'
Tuttavia il vero vantaggio di questo metodo è che ti permette di personalizzare le operazioni di cancellazione degli attributi da una classe.
Ad esempio, riscrivi la classe modificando il metodo '__delattr__()'.
class Persona:
def __init__(self, nome, eta):
self.nome = nome
self.eta = eta
def __delattr__(self, attr):
print(f"Sto per eliminare l'attributo {attr}")
super().__delattr__(attr)
Poi crea un'istanza della classe.
p = Persona("Anna", 30)
Ora cancella l'attributo 'nome' dell'oggetto.
del p.nome
In questo caso Python chiama il metodo '__delattr__()' che hai ridefinito nella classe 'Persona' anziché quello standard, stampando sullo schermo un messaggio prima della rimozione effettiva dell'attributo.
Nota che per cancellare l'attributo si usa il metodo `super().__delattr__(attr)` del comportamento standard di tutte le classi, perché in caso contrario il metodo richiamerebbe quello della classe all'infinito.
Perché personalizzare la procedura di cancellazione?
Immagina di avere un sistema in cui la cancellazione di un attributo potrebbe avere conseguenze importanti o richiedere una sorta di controllo.
Magari prima di eliminare un attributo vuoi verificare che sia sicuro farlo, o vuoi registrare l'operazione in un log.
Ad esempio, riscrivi la classe 'Persona' in questo modo
class Persona:
def __init__(self, nome, eta):
self.nome = nome
self.eta = eta
def __delattr__(self, attr):
if attr == "nome":
# Impedisce la cancellazione dell'attributo 'nome'
print("Non puoi cancellare l'attributo 'nome'!")
else:
# Permette la cancellazione degli altri attributi
super().__delattr__(attr)
In questo caso il metodo '__delattr__()' impedisce la cancellazione dell'attributo 'nome'
Ora crea un oggetto della classe Persona
p = Persona("Anna", 30)
Poi tenta di eliminare l'attributo 'nome'
del p.nome
In questo caso Python ti impedisce la cancellazione dell'attributo.
Non puoi cancellare l'attributo 'nome'!
In conclusione, il metodo `__delattr__()` non è qualcosa che userai ogni giorno, ma è importante sapere che esiste quando devi controllare il comportamento di eliminazione degli attributi di un oggetto.