Functions as values; writing a decorator

Advanced Python for Data Science
Created by Best · 24.06.2026 at 14:03 UTC

In Python, functions are ordinary values: you can pass a function to another function and return a new one. A decorator is exactly that — a function that takes your function and returns a wrapped version, adding behaviour around it without touching what's inside.

@timed
def load_features(path):
    ...

The @timed line is just shorthand for load_features = timed(load_features). Decorators are how production code attaches cross-cutting concerns — timing, logging, retries, caching — once, and reuses them everywhere.

Here's a decorator that reports how long any function it wraps takes to run:

from functools import wraps
import time

def timed(fn):
    @wraps(fn)                       # keep fn's real name and docstring
    def inner(*args, **kwargs):
        t0 = time.perf_counter()
        out = fn(*args, **kwargs)
        print(f"{fn.__name__}: {time.perf_counter() - t0:.4f}s")
        return out
    return inner

The @wraps(fn) matters: without it the wrapper would masquerade under its own name, and the original function would lose its identity for debugging and documentation. Always include it.
leads into “Memoization with lru_cache, safely”.*

University approvals: 0
Related cards
Builds on Explicit stacks and the recursion limit · Python for Data Science
Next Memoization with lru_cache, safely · Python for Data Science
Tasks
Question 1

What is a decorator in Python?

Question 2

Why use functools.wraps inside a decorator?

Card Info
  • Topic: Python for Data Science
  • Difficulty: Advanced
  • Completed: 0 users
Creator
Best
Best
BestBuddy