Python Decorators Explained With Examples
What a decorator actually does to your function You want to time every function that calls a slow external API. You can paste time.perf_counter() calls into each one, or write the measurement once and apply it everywhere. A decorator is the second option. It is a function that takes another function, wraps it in extra behavior, and returns the wrapped version under the original name. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 import time def timed(func): def wrapper(*args, **kwargs): start = time.perf_counter() result = func(*args, **kwargs) elapsed = time.perf_counter() - start print(f"{func.__name__} took {elapsed:.3f}s") return result return wrapper @timed def fetch_price(ticker): time.sleep(0.2) # stand-in for a network call return 142.50 fetch_price("AAPL") # fetch_price took 0.201s @timed above def fetch_price is shorthand for fetch_price = timed(fetch_price). Python calls timed once, right after fetch_price is defined, and rebinds the name fetch_price to whatever timed returns. That’s all the @ does. ...