5.8. Attributs de classe

Vous connaissez déjà les données attributs, qui sont des variables appartenant à une instance particulière d'une classe. Python permet aussi les attributs de classe, qui sont des variables appartenant à la classe elle-même.

Exemple 5.17. Présentation des attributs de 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 est la classe elle-même, pas une instance particulière de cette classe.
2 tagDataMap est un attribut de classe : littéralement, un attribut de la classe. Il est diponible avant qu'aucune instance de la classe n'ait été créée.
3 Les attributs de classe sont disponibles à la fois par référence directe à la classe et par référence à une instance quelconque de la classe.
NOTE
En Java, les variables statiques (appelées attributs de classe en Python) aussi bien que les variables d'instance (appelées données attributs en Python) sont définies immédiatement après la définition de la classe (avec le mot-clé static pour les premières). En Python, seuls les attributs de classe peuvent être définis à cet endroit, les données attributs sont définies dans la méthode __init__.

Les attributs de classe peuvent être utilisés comme des constantes au niveau de la classe (ce qui est la manière dont nous les utilisons dans MP3FileInfo), mais ils ne sont pas vraiment des constantes. Vous pouvez également les modifier.

NOTE
Il n'y a pas de constantes en Python. Tout est modifiable en faisant un effort. C'est en accord avec un des principes essentiels de Python : un mauvais comportement doit être découragé mais pas interdit. Si vous voulez vraiment changer la valeur de None, vous pouvez le faire, mais ne venez pas vous plaindre que votre code est impossible à déboguer.

Exemple 5.18. Modification des attributs de 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 est un attribut de la classe counter.
2 __class__ est un attribut prédéfini de toute instance de classe (de toute classe). C'est une référence à la classe dont self est une instance (dans ce cas, la classe counter).
3 Comme count est un attribut de classe, il est disponible par référence directe à la classe, avant que nous ayions créé une instance de la classe.
4 Créer une instance de la classe appelle la méthode __init__, qui incrémente l'attribut de classe count de 1. Cela affecte la classe elle-même, pas seulement l'instance nouvellement créée.
5 Créer une seconde instance incrémente à nouveau l'attribut de classe count. Vous constatez que l'attribut de classe est partagé par la classe et toutes ses instances.