3.3.2 Personalizzare gli attributi di accesso

Si possono definire i seguenti metodi per personalizzare il significato di accesso agli attributi (l'uso, l'assegnamento o la cancellazione di x.name) delle istanze di classe.

__getattr__( self, name)
Viene chiamato quando la ricerca nelle posizioni usuali di un attributo ha dato esito negativo (per esempio non è un attributo d'istanza e non c'è nemmeno nell'albero di classe per self). Il nome dell'attributo è name. Questo metodo restituisce il valore (calcolato) dell'attributo oppure solleva l'eccezione AttributeError.

Notare che se l'attributo viene individuato mediante il solito meccanismo, la chiamata a __getattr__() non avviene (si tratta di una asimmetria voluta tra __getattr__() e __setattr__()). Questo, allo stesso tempo, succede per ragioni di efficienza e perché altrimenti __setattr__() non avrebbe nessun modo per accedere agli altri attributi dell'istanza. Poi, almeno per le variabili di istanza, se ne può alterare interamente il controllo, non inserendo alcun valore del dizionario degli attributi d'istanza (collocarli invece in un altro oggetto). Vedere più avanti il metodo __getattribute__() per come attualmente si ha il controllo assoluto nelle classi di nuovo stile.

__setattr__( self, name, value)
Chiamato quando viene tentato l'assegnamento di un attributo. È chiamato al posto del normale meccanismo (per esempio memorizzare il valore nel dizionario delle istanze). Il nome dell'attributo è name, value è il valore da assegnargli.

Se __setattr__() vuole assegnare un attributo d'istanza, non basta la semplice esecuzione di "self.name = value" -- ciò causerà una chiamata ricorsiva a se stesso. Invece, deve inserire il valore nel dizionario degli attributi d'istanza: ad esempio "self.__dict__[name] = value". Le classi di nuovo stile, piuttosto che accedere al dizionario delle istanze, devono chiamare il metodo della classe base avente lo stesso nome: per esempio, "object.__setattr__(self, name, value)".

__delattr__( self, name)
Funziona come __setattr__(), ma per la cancellazione dell'attributo invece dell'assegnamento. Dovrebbe essere implementato solo se per l'oggetto è significativo "del obj.name".



Subsections
Vedete Circa questo documento... per informazioni su modifiche e suggerimenti.