Un blog bastante personal para acordarme de esas pequeñas cosas que luego nos hacen perder el tiempo a lo tonto, y si a alguien le interesa ... pues tan ricamente.
jueves, 28 de julio de 2011
Decoradores en python (I)
Llevo poco tiempo programando en python, y una de las cosas que más me ha sorpendido es el tema de los decoradores.
Estan basado en el patron decorador, y existen tambien en otros lenguajes, pero en python esta muy bien integrado.
Los decoradores nos sirven para añadir nuevas funcionalidades a codigo ya existente, o reutilizar código de forma más eficiente, y sobre todo tambien, para que quede el codigo más legible.
En está pagina podemos ver que lo utiliza para evitar la repetición de código, y para que quede más clara.
A continuación voy a poner un ejemplo muy simple de decorador, que simplemente nos dice cuando se ejecuta la parte perteneciente al decorador con un print:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# Nuestro decorador
def saluda_antes(funcion):
print "Codigo antes de decorar la funcion"
def nueva_funcion(*args, **kwargs):
print "Ejecuto la funcion decorada"
return funcion(*args, **kwargs)
print "Codigo despues de decorar la funcion"
return nueva_funcion
# Nuestra funcion
def sumar(a, b):
print "Ejecutando suma"
return a+b
# Main
if __name__ == '__main__':
sol = sumar(2, 3)
print "Solucion {0}\n".format(sol)
print "Decoramos la funcion_______________"
sumar = saluda_antes(sumar)
print "Funcion ya decorada________________\n"
sol = sumar(2, 3)
print "Solucion {0}".format(sol)
Que nos genera la siguiente salida:
Ejecutando suma
Solucion 5
Decoramos la funcion_______________
Codigo antes de decorar la funcion
Codigo despues de decorar la funcion
Funcion ya decorada________________
Ejecuto la funcion decorada
Ejecutando suma
Solucion 5
En el primer bloque vemos la funcion sumar a secas.
En el segundo la salida que nos muestra es la que obtenemos mientras se aplica el decorador.
Y por ultimo tenemos el resultado de lanzar la funcion con el decorador aplicado.
Otra manera de lanzar el decorador es poniendo la @nombre_decorador encima de la función.
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# Nuestro decorador
def saluda_antes(funcion):
print "Codigo antes de decorar la funcion"
def nueva_funcion(*args, **kwargs):
print "Ejecuto la funcion decorada"
return funcion(*args, **kwargs)
print "Codigo despues de decorar la funcion"
return nueva_funcion
# Nuestra funcion
@saluda_antes
def sumar(a, b):
print "Ejecutando suma"
return a+b
# Main
if __name__ == '__main__':
sol = sumar(2, 3)
print "Solucion {0}".format(sol)
Que genera una salida ligeramente diferente:
Codigo antes de decorar la funcion
Codigo despues de decorar la funcion
Ejecuto la funcion decorada
Ejecutando suma
Solucion 5
Podemos ver que lo primero que se ejecuta es el código que hay al decorar la funcion, seguido por el código del decorador, y por último el de la funcion.
Creo que queda claro, pero solo quiero aclarar que el codigo que se ejecuta al decorar la funcion (al principio), sólo se ejecuta una única vez. Si hicieramos 4 llamadas seguidas, tendriamos algo tal que así:
Codigo antes de decorar la funcion
Codigo despues de decorar la funcion
Ejecuto la funcion decorada
Ejecutando suma
Solucion 5
Ejecuto la funcion decorada
Ejecutando suma
Solucion 5
Ejecuto la funcion decorada
Ejecutando suma
Solucion 5
Ejecuto la funcion decorada
Ejecutando suma
Solucion 5
Y hasta aquí lo que se daba.
Volvere con más operadores cuando aprenda un poco más sobre ellos (paso de parametros, autocreacion de decoradores, etc).
Suscribirse a:
Enviar comentarios (Atom)
Hola!.
ResponderEliminarEso de que están basados en el patrón decorador... no lo veo tan claro, en otros artículos dicen lo contrario.. te paso uno de ellos:
http://www.3engine.net/wp/2015/02/decoradores-python/