Decora tu código (Python decorators)
Los decoradores de Python ofrecen una forma elegante de aplicar wrappers a clases, métodos y propiedades.
La sintaxis es la siguiente:
>>> @decorador>>> def funcion_decorada():>>> return 'resultado'>>>>>> print funcion_decorada()resultado>>>
y básicamente, significa lo mismo que el siguiente trozo de código:
>>> def funcion():>>> return 'resultado'>>>>>> funcion_decorada = decorador(funcion)>>>>>> print funcion_decorada()resultado>>>
Un decorador es una función que:
- - recibe una función como parámetro y
- - devuelve otra función como resultado.
Completando nuestro primer ejemplo, el siguiente decorador:
>>> def decorador(funcion):>>>>>> def nuevaFuncion(*args, **kwargs):>>> print 'pamplinas'>>> return funcion(*args, **kwargs)>>>>>> return nuevaFuncion>>>
modifica el comportamiento de nuestra función de la siguiente manera:
>>> print funcion_decorada()pamplinasresultado>>>
Un aplicación típica de los decoradores es en la definición de métodos de clase. Tradicionalmente se ha utilizado esta sintáxis:
>>> def metodo(self):>>> return 'resultado'>>>>>> metodo_de_clase = classmethod(metodo)>>>
Si el cuerpo del método es muy largo, puede quedarnos poco legible el código. Los decoradores nos permiten abreviar bastante:
>>> @classmethod>>> def metodo_de_clase(self):>>> return 'resultado'
Los decoradores tienen numerosas aplicaciones, por ejemplo, podemos implementar una política de “Dreprecation Warnings” de la siguiente manera:
>>> import warnings>>>>>> def deprecated(funcion):>>> >>> def nuevaFuncion(*args, **kwargs):>>> warnings.warn(funcion.__name__, DeprecationWarning, stacklevel=2)>>> return funcion(*args, **kwargs)>>> >>> nuevaFuncion.__name__ = funcion.__name__>>> nuevaFuncion.__doc__ = funcion.__doc__>>> nuevaFuncion.__dict__.update(funcion.__dict__)>>> return nuevaFuncion>>> >>> >>> class MiClase:>>> >>> @deprecated>>> def metodo_anticuado(self):>>> return 'resultado'>>> >>> miClase = MiClase()>>>>>> r = miClase.metodo_anticuado()DeprecationWarning: metodo_anticuado>>>
Referencias:
Share your source code
Tagging the planet
Noviembre 09, 2006 - 11:05 pm
Qué grandes son. Cuando estuve viendo la librería de decoradores [1] fue como
Vienen al pelo para logging u otros elementos rollo aspectos, o para expresar de manera clara restricciones a funciones, o incluso para transformar parámetros de un tipo a otro (rollo “de verdad recibo usuario y passwd de una BD” y las funciones que tengo las implemento como que recibo cursores diréctamente).Es lo que dices, nada que no se pudiese hacer antes en plan:def micodigo(bla): ble blemicodigo = decorador(micodigo)pero de una forma más elegante.[1] http://wiki.python.org/moin/PythonDecoratorLibrary
Noviembre 10, 2006 - 7:21 am
Aupi NcTrun,Buena referencia! No conozco mucho sobre ‘aspectos’, a ver si nos escribes algo sobre ello! ;-DAgur,Nando.