Skip to content

Commit cddab39

Browse files
authored
Merge pull request mouredev#4235 from neslarra/patch-35
Reto# 24 - python
2 parents d76a710 + fc73677 commit cddab39

File tree

1 file changed

+159
-0
lines changed

1 file changed

+159
-0
lines changed
+159
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
"""
2+
EJERCICIO:
3+
Explora el concepto de "decorador" y muestra cómo crearlo
4+
con un ejemplo genérico.
5+
DIFICULTAD EXTRA (opcional):
6+
Crea un decorador que sea capaz de contabilizar cuántas veces
7+
se ha llamado a una función y aplícalo a una función de tu elección.
8+
"""
9+
10+
print(f"{'#' * 47}")
11+
print(f"## Explicación {'#' * 30}")
12+
print(f"{'#' * 47}")
13+
14+
print(r"""
15+
Los decoradores son funciones que modifican el comportamiento de otras funciones. Pueden ser los que entrega Python por default (por ejemplo
16+
staticmethod y classmethod) o funciones creadas para determinada función.
17+
18+
Por ejemplo, creo una clase Turno para entregar turnos de una tienda con varios sectores. La clase Turno tendrá tres métodos decorados:
19+
1- hora_de_emision decorado con "staticmethod" indicando que es de clase PERO no recive ni entrega argumentos de la clase.
20+
2- localiza_sector decorado con "classmethod" indicanco que es de clase y entregando el contenido de una variable de la clase.
21+
3- entrega_de_turno decorado con "classmethod" indicando que es de clase y modificando y entregando una variable de clase.
22+
23+
Luego tenemos el decorador "asesor" el cual se encarga de ejecutar comandos pre y post callback de la función decorada (va a dar instrucciones
24+
de localización, va a llamar a la función que muestra el turno y luego va a hacer un saludo final).
25+
26+
Los decoradores se invocan con un "@"<nombre_de_la_función_decoradora> justo antes de definir la función decorada.
27+
28+
def mi_decorador(callback_func):
29+
def wrapper(*args, **kwargs)
30+
<ejecuto PRE operaciones>
31+
callback_func(*args, **kwargs)
32+
<ejecuto POST operaciones>
33+
return wrapper
34+
35+
@mi_decorador
36+
def funcion_decorada():
37+
...
38+
39+
Ejemplo:
40+
41+
from time import sleep
42+
43+
44+
class Turno:
45+
turno: int = 1000
46+
ubicacion = {"Farmacia": "por pasillo central al fondo",
47+
"Perfumería": "por escalera primer piso",
48+
"Gabinete": "por pasillo de la derecha"}
49+
50+
def __init__(self, sector):
51+
self.sector = sector
52+
self.hora = self.hora_de_emision()
53+
self.turno = Turno.entrega_turno()
54+
55+
@staticmethod
56+
def hora_de_emision():
57+
from datetime import datetime
58+
return datetime.now().strftime('%H:%M:%S')
59+
60+
@classmethod
61+
def localiza_sector(cls, sector):
62+
return cls.ubicacion[sector]
63+
64+
@classmethod
65+
def entrega_turno(cls):
66+
cls.turno += 1
67+
return cls.turno
68+
69+
70+
def asesor(funcion_decorada):
71+
def wrapper(*args, **kwargs):
72+
# *args, **kwargs son los argumentos de la función decorada "ver_turno: args[0] = nombre y args[1] L instancia del objeto Turno"
73+
print(f"{args[0]} dirijase {args[1].localiza_sector(args[1].sector)}")
74+
funcion_decorada(*args, **kwargs)
75+
print("Gracias por su visita.\n")
76+
77+
return wrapper
78+
79+
80+
@asesor
81+
def ver_turno(nombre, turno):
82+
print(f"Tiene el turno {turno.turno} de la hora {turno.hora} para {turno.sector}")
83+
84+
85+
nestor = Turno("Farmacia")
86+
sleep(1)
87+
neslarra = Turno("Farmacia")
88+
sleep(1)
89+
nesla = Turno("Perfumería")
90+
sleep(1)
91+
otro_nestor = Turno("Gabinete")
92+
93+
ver_turno("Néstor", nestor)
94+
ver_turno("Neslarra", neslarra)
95+
ver_turno("Nesla", nesla)
96+
ver_turno("Otro Néstor", otro_nestor)
97+
98+
Ésto devuelve:
99+
100+
Néstor dirijase por pasillo central al fondo # decorador PRE operación
101+
Tiene el turno 1001 de la hora 18:28:14 para Farmacia # función decorada
102+
Gracias por su visita. # decorador POST operación
103+
104+
Neslarra dirijase por pasillo central al fondo # decorador PRE operación
105+
Tiene el turno 1002 de la hora 18:28:15 para Farmacia # función decorada
106+
Gracias por su visita. # decorador POST operación
107+
108+
Nesla dirijase por escalera primer piso # decorador PRE operación
109+
Tiene el turno 1003 de la hora 18:28:16 para Perfumería # función decorada
110+
Gracias por su visita. # decorador POST operación
111+
112+
Otro Néstor dirijase por pasillo de la derecha # decorador PRE operación
113+
Tiene el turno 1004 de la hora 18:28:17 para Gabinete # función decorada
114+
Gracias por su visita. # decorador POST operación
115+
""")
116+
117+
print(f"{'#' * 52}")
118+
print(f"## Dificultad Extra {'#' * 30}")
119+
print(f"{'#' * 52}\n")
120+
121+
def contador_de_ejecuciones(funcion):
122+
ejecuciones = {}
123+
def wrapper(*args, **kwargs):
124+
ejecuciones[funcion.__name__] = ejecuciones[funcion.__name__] if funcion.__name__ in ejecuciones.keys() else 0
125+
print(f"Ejecutando {funcion.__name__}", end="\n\t")
126+
funcion(*args)
127+
ejecuciones[funcion.__name__] += 1
128+
print(f"{funcion.__name__} se ha ejecutado {ejecuciones[funcion.__name__]} veces.\n")
129+
return wrapper
130+
131+
132+
@contador_de_ejecuciones
133+
def saludo_espaniol(nombre):
134+
print(f"{nombre} Hola Mundo")
135+
136+
137+
@contador_de_ejecuciones
138+
def saludo_ingles(nombre):
139+
140+
print(f"{nombre} Hello World")
141+
@contador_de_ejecuciones
142+
def saludo_frances(nombre):
143+
print(f"{nombre} Alo Monde")
144+
145+
@contador_de_ejecuciones
146+
def saludo_italiano(nombre):
147+
print(f"{nombre} Ciao Mondo")
148+
149+
150+
saludo_ingles("Pete")
151+
saludo_italiano("Peppo")
152+
saludo_ingles("Joe")
153+
saludo_ingles("Jhonny")
154+
saludo_espaniol("Tonio")
155+
saludo_espaniol("Pepe")
156+
saludo_italiano("Gianni")
157+
saludo_frances("Peppete")
158+
saludo_frances("Jean")
159+
saludo_italiano("Carletto")

0 commit comments

Comments
 (0)