5.8. Presentación de los atributos de clase

Ya conoce los atributos de datos, que son variables que pertenecen a una instancia específica de una clase. Python también admite atributos de clase, que son variables que pertenecen a la clase en sí.

Ejemplo 5.17. Presentación de los atributos de clase


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 es la clase en sí, no una instancia en particular de la clase.
2 tagDataMap es un atributo de la clase: literalmente. Está disponible antes de crear cualquier instancia de la clase.
3 Los atributos de clase están disponibles tanto haciendo referencia directa a la clase como a cualquiera de sus instancias.
nota
En Java, tanto las variables estáticas (llamadas atributos de clase en Python) como las variables de instancia (llamadas atributos de datos en Python) se declaran inmediatamente en la definición de la clase (unas con la palabra clave static, otras sin ella). En Python, sólo se pueden definir aquí los atributos de clase; los atributos de datos se definen en el método __init__.

Los atributos de clase se pueden usar como constantes de la clase (que es para lo que las usamos en MP3FileInfo), pero no son constantes realmente. También puede cambiarlas.

nota
No hay constantes en Python. Todo puede cambiar si lo intenta con ahínco. Esto se ajusta a uno de los principios básicos de Python: los comportamientos inadecuados sólo deben desaconsejarse, no prohibirse. Si en realidad quiere cambiar el valor de None, puede hacerlo, pero no venga luego llorando si es imposible depurar su código.

Ejemplo 5.18. Modificación de atributos de clase

>>> 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 es un atributo de clase de la clase counter.
2 __class__ es un atributo incorporado de cada instancia de la clase (de toda clase). Es una referencia a la clase de la que es instancia self (en este caso, la clase counter).
3 Debido a que count es un atributo de clase, está disponible por referencia directa a la clase, antes de haber creado instancias de ella.
4 Crear una instancia de la clase llama al método __init__, que incrementa el atributo de la clase count en 1. Esto afecta a la clase en sí, no sólo a la instancia recién creada.
5 Crear una segunda instancia incrementará el atributo de clase count de nuevo. Advierta cómo la clase y sus instancias comparten el atributo de clase.