Functions That Wrap Functions

Scenario: Every deployment function needs identical timing and audit logging.

New words, in plain English

Functions are values, so another function can wrap them. Accept args, *kwargs, return the original result, and use functools.wraps to preserve metadata.

Analogy: A Python program is like a clear set of instructions for a careful helper: names label things, indentation groups steps, and errors explain where the helper became confused.

A small, real example

from functools import wraps
def logged(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        print(f"calling {func.__name__}")
        return func(*args, **kwargs)
    return wrapper
Tip: A decorator must preserve return values and exceptions unless changing them is its explicit contract.
Goal: Practice this idea in the py-decorators challenge at /labs/python. Fix the broken program, run it yourself, then use check to prove the real end state.