Un decorador en python es esta cosa por si la han visto:
@decorador
En el código python,un decorador se usa para "modificar" una función anidandola dentro de otra,veamos un código y a continuación lo explico:
Primero que nada ya deben conocer y saber usar args y kwargs:
Enlace
Bien vamos a crear un modificador que saluda a la funcion recibida :
1 2 3 4 5 6 7 8 9 10 11 12 | def ver(fun): def _ver(*args,**kwargs): print "Bienvenido ",fun.__name__ fun(*args,**kwargs) print "Adios ",fun.__name__ return _ver @ver def sumar(x,y): print x+y sumar(1,4) |
Bien al ejecutar podrán ver algo como lo siguiente:
Bienvenido sumar
5
Adios sumar
Aquí lo que estamos haciendo es muy raro en la sintaxis común de python,porque de donde salio ese arroba no es perl o ruby para usar arrobas ,en python a eso se le llama decoradores,un decorador es una función anidada que ejecuta la función recibida y la decora adentro de otra función que retorna:
Veamos:
def ver(fun) # Esta es la función decoradora,el parámetro que recibe es la misma a decorar(la que esta abajo del arroba)
def _ver(*args,**kwargs) # Esta es la función modificada,adentro ejecutamos la función recibida y la decoramos
print "Bienvenido ",fun.__name__ # Ejecutamos esto como ejemplo de decoración(le damos la bienvenida a la funcion)
fun(*args,**kwargs) # Ejecutamos la función recibida(como si fuera la ejecución real),los parámetros los "hereda"(son los mismos)
print "Adios ",fun.__name__ # Nos despedimos de la función(podríamos decir que termina)
return _ver # Retornamos la función modificada o que modifico la función principal(la que ejecuto)
Bien,como vemos es sencillo solo que un poco raro ver esto en python,vamos a ver que contienen los args y kwargs:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | #!/usr/bin/nev python def ver(fun): def _ver(*args,**kwargs): print "Bienvenido ",fun.__name__ for i in args: print i,"<- adentro="" del="" font="" modificador=""> for k,v in kwargs.iteritems(): print "Key : %s Value : %s <- adentro="" del="" font="" modificador=""> %(k,v) fun(*args,**kwargs) print "Adios ",fun.__name__ return _ver @ver def sumar(x,y,**k): print x+y,"<- en="" font="" funcion="" la="" real=""> sumar(1,4,uno=1) ->->-> |
En este caso los args y kwargs son los que le pasamos a la hora de llamarlo,por ejemplo toma de args todos los argumentos en una tupla y los kwargs todos los argumentos de clave valor,para así poder trabajar con ellos dentro del decorador por si los necesitamos,veamos un ejemplo:
Supongamos que queremos multiplicar todos los números recibidos de una funcion principal pero vamos a sumarlos también en otra función solo vamos a mostrarlos,lo cual es dos funciones una que suma y multiplica y otra que no suma solo muestra los números,podemos hacerlo 10 veces por ejemplo 7 que hagan algo con los números y 3 que solo hagan su función:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | #!/usr/bin/nev python def sumar(fun): def _sumar(*args,**kwargs): iterador = 0 for i in args: iterador += i fun(*args,**kwargs) print "Suma de todos los numeros ",iterador return _sumar @sumar def multiplica(x,y,z,n): # Esta funcion multiplica todos los numeros print x*y*z*n #@sumar # Si quitamos el gato tambien tendra el decorador sumar def muestra(x,y,z,i): # Esta solo los muestra print "Numeros %d %d %d %d" %(x,y,z,i) multiplica(1,2,3,4) muestra(2321,321,545,565) |
Bien como vemos es un uso muy raro el ejemplo pero es un ejemplo del uso de los decoradores,los ejemplos no son practica son aprendizaje así que esta bien.
Podemos usar decoradores con parámetros,por ejemplo vamos a ejecutar una función cierto numero de veces basado en el decorador:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | #!/usr/bin/nev python def rep(n): def iterador(fun): def _rep(*args,**kwargs): for i in range(0,n): fun(*args,**kwargs) return _rep return iterador @rep(10) def multiplica(x,y,z,n): # Esta funcion multiplica todos los numeros print x*y*z*n multiplica(1,2,3,4) |
Ahora lo explico:
Lo primero que hicimos fue bajar otro nivel en las funciones anidadas del decorador,el primer nivel a hora no es el que recibe la función si no el que recibe el argumento pasado al decorador:
def rep(n) # n = 10 porque @rep(10)
En la función iterador el segundo nivel de función es donde ahora recibimos la función (el decorador):
def iterador(fun) # fun = multiplica
El ultimo nivel de función es (el modificador):
def _rep(*args,**kwargs) # Modificador
En cada función en un nivel mas alto debemos retornar una función,ya que detiene la función y continua con el iterador.
return _rep termina con _rep,return iterador termina con iterador.
Como vemos los modificadores son buenos para ciertas practicas pero no son indispensables,podemos remplazarlos con funciones comunes u otras practicas,pero es bueno usarlos en ocasiones especiales.
No hay comentarios.:
Publicar un comentario
Los comentarios serán revisados antes de ser publicados.