Decorators and Higher-order functions

When you see @cl.on_message or @app.route("/api"), that @ symbol is a decorator. Decorators wrap a function with extra behavior (logging, timing, registration) and power Chainlit, FastAPI, Flask, and every modern Python framework.

Decorator wrapping

How a decorator wraps a function with extra behavior

decorators.py
python
# Functions are objects (you can pass them around)
def shout(text):
    return text.upper() + "!"

def whisper(text):
    return text.lower() + "..."

# Choose a function based on a condition
formatter = shout
print(formatter("hello"))  # HELLO!

# Pass a function to another function
def apply(func, text):
    return func(text)

print(apply(whisper, "HELLO"))  # hello...

In Python, functions are objects. You can assign them to variables and pass them as arguments. This is the foundation of decorators.

@decorator above a function is syntactic sugar for: my_func = decorator(my_func). The decorator receives your function, wraps it with extra behavior, and returns the wrapped version. Your original function is replaced by the wrapper.

decorators.py
python
import time

# Writing a decorator
def timer(func):
    def wrapper(*args, **kwargs):
        start = time.time()
        result = func(*args, **kwargs)
        elapsed = time.time() - start
        print(f"{func.__name__} took {elapsed:.3f}s")
        return result
    return wrapper

@timer
def slow_search(items, query):
    time.sleep(0.1)  # Simulate work
    return [item for item in items if query.lower() in item.lower()]

menu = ["Mushroom Burger", "Quinoa Bowl", "Cashew Mac", "Tofu Tacos"]
results = slow_search(menu, "o")
print(f"Found: {results}")

The timer decorator wraps slow_search: it records the start time, calls the original function, then prints the elapsed time. This is exactly how Chainlit registers message handlers.

Quiz: Quiz

Loading practice…

Fill in the blanks: Complete the decorator

Loading practice…

Validation checklist: Decorators checklist

Loading practice…

Checkpoint: Oop Python checkpoint

Loading practice…

Timed quiz: Oop speed round

Loading practice…