Atributos con tipado estático en Python (usando un descriptor)
En esta receta voy a contar cómo utilizar los «descriptores» de Python para poder crear atributos (variables de instancia) que no puedan cambiar de tipo durante la vida del objeto. Por supuesto, también es una excusa para aprender algo sobre los descriptores en sí.
Requisitos
- Python >= 2.2 (se necesitan clases del «nuevo estilo», las que heredan de
object
). - Conocimientos precisos sobre los mecanismos de introspección de Python.
Descriptores
Los descriptores de Python son clases que implementan un «protocolo» concreto, es decir, una serie de métodos. A saber:
Aunque esto parezca bastante extraño, lo cierto es que los descriptores se usan en la mayoría de componentes del lenguaje: funciones, métodos estáticos y de clase, properties y muchas otras cosas. La Descriptor HowTo Guide define el descriptor como «un atributo de objeto con comportamiento asociado», y eso es porque es posible añadir código que se ejecutar cuando se pida (get), se asigne (set) o se destruya un atributo creado con un descriptor.
Se distingue entre «data descriptors» si definen __get__
y __set__
y «non-data descriptors» si solo definen el __get__
. Esta diferencia afecta al comportamiento del descriptor en lo referente al método __get__
aunque ambos lo tienen. No voy a entrar más en detalle sobre esto porque aquí vamos a hacer un «data descriptor».
Tipado estático
Nuestro descriptor nos va a permitir definir el tipo de un atributo al declarar la clase. No será posible cambiar el tipo del atributo operando con las instancias de la clase, aunque sí el valor. El descriptor sería algo como:
Y se usa de este modo:
Puedes encontrar este descriptor en la última versión del paquete python-pyarco
Referencias
- “Python: Typed attributes using descriptors ":http://kbyanc.blogspot.com/2007/08/python-typed-attributes-using.html
- Python: Decorator Classes On The Edge