Decoradores en Python (I)

Un decorador es una función que retorna otra función, por lo general aplicada a la transformación de una función usando la sintaxis @wrapper.

Cómo funcionan los decoradores?

Básicamente y para que lo entendamos, podemos decir que un decorador es una función que recibe como parámetro a otra función y retorna una función nueva. Por ejemplo: una función decoradora (B) que recibe a una función a decorar (A) y retorna la función decorada (R). La nueva función (R) será el resultado de decorar con (B) a la función (A).

Por consiguiente: A = B(A).

De ahora en adelante A será la nueva función decorada.

Miremos paso a paso la definición y ejecución de una estructura decoradora.

Supongamos que tenemos la función:

 >>> def funcion(n1, n2):
 ...     return (n1 + n2)
 ...
 >>>

Estructura decoradora:

>>> def decoradora(funcion_a_decorar):
...     def decorada(*args, **kwargs):
...             print "Inicio ejecución de", funcion_a_decorar.__name__
...             return str(funcion_a_decorar(*args, **kwargs))
...             print "Fin ejecución de", funcion_a_decorar.__name__
...     return decorada
... 
>>>

ejecución función sin decorar:

 >>> funcion(3,5)
 8
 >>>

ejecución función decoradadora:

>>> decorar = decoradora(funcion)
>>> decorar(3,5)
Inicio ejecución de funcion
'8'
>>>

Como necesitamos que se siga ejecutando nuestro decorador hasta el final:

>>> def decoradora(funcion_a_decorar):
...     def decorada(*args, **kwargs):
...             print "Inicio ejecución de", funcion_a_decorar.__name__
...             print funcion_a_decorar(*args, **kwargs)
...             print "Fin ejecución de", funcion_a_decorar.__name__
...     return decorada
... 
>>> decorar = decoradora(funcion)
>>> decorar(3,5)
Inicio ejecución de funcion
8
Fin ejecución de funcion
>>>

Sin Azúcar Sintáctica.

Así mismo podemos guardar dentro  de “funcion” la versión decorada de “funcion” y ahora nunca más a lo largo del programa se tendrá acceso a la versión original.

sintasix:
 def mi_funcion():
 pass
 mi_funcion = staticmethod(mi_funcion)
 >>>
 >>> funcion = decoradora(funcion)
 >>> funcion(3,5)
 Inicio ejecución de funcion
 8
 Fin ejecución de funcion
 >>>

La conclusión entonces es que los decoradores nos permiten agregar funcionalidad adicional a una función o clase.

Con Azúcar Sintáctica.

A partir de Python 2.4 se ha añadido azúcar sintáctica al lenguaje, incorporando la notación con “@” que nos permite hacer lo mismo de esta forma:

sintaxis:
 @staticmethod
 def mi_funcion():
 pass
 >>> @decoradora
 ... def funcion(n1, n2):
 ...     return (n1 + n2)
 ...
 >>> funcion(6,8)
 Inicio ejecución de funcion1
 14
 Fin ejecución de funcion1
 >>>

Supongamos que tenemos una función que retorna un número, pero necesitamos que de ahora en adelante esta función nos devuelva todo como un string.

 >>> def to_string(a): # Función decoradora
 ...     def r(*args, **kwargs): # Función decorada
 ...             # comportamiento previo a la ejecución de a
 ...             return str(f(*args, **kwargs)) # Aquí termina la ejecución ya que llamamos a 'return'
 ...             # comportamiento posterior a la ejecución de a
 ...     return r
 ...
 >>> @to_string
 ... def count(n):
 ...     return n
 ...
 >>> count(7)
 '7'
 >>> count(2342929)
 '2342929'
 >>>

Qué usos podrían tener los decoradores?

Supongamos que tenemos una aplicación donde necesitamos que ciertas funciones se ejecuten sólo si el usuario es el administrador. No necesitamos escribir todas las funciones para los distintos roles que existan en nuestro aplicativo, tan solo necesitariamos usar un decorador en las funciones de administración para comprobar que efectivamente el usuario es administrador.

Author: Jolth

Anuncios

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s