4.8. Attributi di classe

Conoscete già gli attributi dato, che sono variabili di una specifica istanza di una classe. Python supporta anche gli attributi di classe, che sono variabili riferite alla classe stessa.

Esempio 4.18. Introdurre gli attributi di classe


class MP3FileInfo(FileInfo):
    "store ID3v1.0 MP3 tags"
    tagDataMap = {"title"   : (  3,  33, stripnulls),
                  "artist"  : ( 33,  63, stripnulls),
                  "album"   : ( 63,  93, stripnulls),
                  "year"    : ( 93,  97, stripnulls),
                  "comment" : ( 97, 126, stripnulls),
                  "genre"   : (127, 128, ord)}
>>> import fileinfo
>>> fileinfo.MP3FileInfo            1
<class fileinfo.MP3FileInfo at 01257FDC>
>>> fileinfo.MP3FileInfo.tagDataMap 2
{'title': (3, 33, <function stripnulls at 0260C8D4>),
'genre': (127, 128, <built-in function ord>), 
'artist': (33, 63, <function stripnulls at 0260C8D4>), 
'year': (93, 97, <function stripnulls at 0260C8D4>), 
'comment': (97, 126, <function stripnulls at 0260C8D4>),
'album': (63, 93, <function stripnulls at 0260C8D4>)}
>>> m = fileinfo.MP3FileInfo()      3
>>> m.tagDataMap
{'title': (3, 33, <function stripnulls at 0260C8D4>), 
'genre': (127, 128, <built-in function ord>), 
'artist': (33, 63, <function stripnulls at 0260C8D4>), 
'year': (93, 97, <function stripnulls at 0260C8D4>), 
'comment': (97, 126, <function stripnulls at 0260C8D4>),
'album': (63, 93, <function stripnulls at 0260C8D4>)}
1 MP3FileInfo è la classe stessa, non una particolare istanza della classe.
2 tagDataMap è un "class attribute": letteralmente, un attributo della classe. È disponibile prima di ogni istanza della classe.
3 Gli attributi di classe sono disponibili sia attraverso un riferimento diretto alla classe che attraverso qualunque istanza della classe.
Nota
In Java, sia le variabili statiche (chiamate attributi di classe in Python) che le variabili di istanza (chiamate attributi dato in Python), sono definite immediatamente dopo la definizione della classe (il primo con la parola chiave static, il secondo senza). In Python, solo gli attributi di classe posso essere definiti così; gli attributi dato sono definiti nel metodo __init__.

Gli attributi di classe possono essere usati come costanti a livello di classe (cioè il modo in cui li usiamo in MP3FileInfo), ma non sono realmente costanti. [4] Potete anche modificarli.

Esempio 4.19. Modificare gli attributi di classe

>>> class counter:
...     count = 0                     1
...     def __init__(self):
...         self.__class__.count += 1 2
...     
>>> counter
<class __main__.counter at 010EAECC>
>>> counter.count                     3
0
>>> c = counter()
>>> c.count                           4
1
>>> counter.count
1
>>> d = counter()                     5
>>> d.count
2
>>> c.count
2
>>> counter.count
2
1 count è un attributo di classe della classe counter.
2 __class__ è un attributo built-in di ogni istanza della classe (di ogni classe). È un riferimento alla classe di cui self è un'istanza (in questo caso, la classe counter).
3 Dato che count è un attributo di classe, è quindi disponibile attraverso un riferimento diretto, prima di aver creato una qualunque istanza della classe.
4 Creando un'istanza della classe viene chiamato il metodo __init__, che incrementa l'attributo di classe count di 1. Questo ha effetto sulla classe stessa, non solo sull'istanza appena creata.
5 Creando una seconda istanza della classe verrà incrementato di nuovo l'attributo di classe count. Notate come l'attributo di classe venga condiviso dalla classe e da tutte le sue istanze.

Footnotes

[4] Non ci sono costanti in Python. Ogni cosa può essere modificata se provate abbastanza. Questo fa parte di uno dei principali concetti di Python: cattivi comportamenti dovrebbero essere scoraggiati, ma non impediti. Se volete veramente modificare il valore di None, potete farlo, ma non venite correndo da me se il vostro codice diventa impossibile da debuggare.