How do decorators work? Write a decorator that logs how long a function takes.
Answer
- Functions are objects: you can pass them around and return them.
@deco above def f means f = deco(f).- The decorator returns a wrapper that runs code before/after calling the original.
- Use
functools.wraps to keep the original name and docstring. - With arguments you add a factory level:
@retry(3) means f = retry(3)(f).
import functools, time
def timed(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
start = time.perf_counter()
try:
return func(*args, **kwargs)
finally:
ms = (time.perf_counter() - start) * 1000
print(f"{func.__name__} took {ms:.1f} ms")
return wrapper
Practice this question in Repaso