Skip to content

Commit 1a73eca

Browse files
#24 - python
1 parent 59e7fea commit 1a73eca

File tree

1 file changed

+95
-0
lines changed

1 file changed

+95
-0
lines changed
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
#24 { Retos para Programadores } PATRONES DE DIESEÑO: DECORADORES
2+
3+
# Bibliography reference
4+
# I use GPT as a reference and sometimes to correct or generate proper comments.
5+
6+
"""
7+
* EJERCICIO:
8+
* Explora el concepto de "decorador" y muestra cómo crearlo
9+
* con un ejemplo genérico.
10+
*
11+
* DIFICULTAD EXTRA (opcional):
12+
* Crea un decorador que sea capaz de contabilizar cuántas veces
13+
* se ha llamado a una función y aplícalo a una función de tu elección.
14+
15+
"""
16+
17+
log = print
18+
log('Retos para Programadores #24')
19+
20+
# The decorator pattern is a structural design pattern that allows behavior to be added
21+
# to individual objects, either statically or dynamically, without affecting the behavior
22+
# of other objects from the same class. In Python, decorators are implemented using
23+
# higher-order functions.
24+
25+
import time
26+
import functools
27+
28+
# Generic decorator function
29+
def decorator(fn):
30+
@functools.wraps(fn)
31+
def wrapper(*args, **kwargs):
32+
print("Before calling the function")
33+
result = fn(*args, **kwargs)
34+
print("After calling the function")
35+
return result
36+
return wrapper
37+
38+
# Decorator to log execution time
39+
def log_execution_time(fn):
40+
@functools.wraps(fn)
41+
async def wrapper(*args, **kwargs):
42+
start = time.time() # Start time
43+
result = await fn(*args, **kwargs)
44+
end = time.time() # End time
45+
print(f"Execution time for {fn.__name__}: {(end - start) * 1000:.2f} milliseconds")
46+
return result
47+
return wrapper
48+
49+
# Example function that simulates a time-consuming task
50+
async def fetch_data():
51+
await asyncio.sleep(3) # Simulate a delay of 3 seconds
52+
return "Data fetched!"
53+
54+
# Decorated function
55+
logged_fetch_data = log_execution_time(fetch_data)
56+
57+
# Using the decorated function
58+
import asyncio
59+
60+
async def main():
61+
result = await logged_fetch_data()
62+
print(result) # Data fetched!
63+
64+
65+
# Run the main function
66+
asyncio.run(main()) # Data fetched!
67+
# Execution time for fetch_data: 3008.05 milliseconds
68+
69+
# EXTRA DIFFICULTY EXERCISE
70+
71+
# Decorator to count function calls
72+
def count_calls(fn):
73+
call_count = 0 # Private variable to keep track of calls through closure
74+
75+
@functools.wraps(fn)
76+
def wrapper(*args, **kwargs):
77+
nonlocal call_count
78+
call_count += 1
79+
print(f"Function has been called {call_count} times.")
80+
return fn(*args, **kwargs)
81+
return wrapper
82+
83+
# Original function
84+
@count_calls
85+
def hi_girl():
86+
print('Hi Girl! 🌹')
87+
return '🌼'
88+
89+
# Using the decorated function
90+
print(hi_girl()) # Function has been called 1 times. Hi Girl! 🌹
91+
print(hi_girl()) # Function has been called 2 times. Hi Girl! 🌹
92+
print(hi_girl()) # Function has been called 3 times. Hi Girl! 🌹
93+
94+
# Trying to access hi_girl directly will not result in an error, but the call count will still be tracked.
95+

0 commit comments

Comments
 (0)