POST 1 of 5 MorningPythonConcept
A decorator is just a function that returns a function
If there's one Python feature that consistently scares newcomers and confuses intermediates, it's the decorator. Take away the @ syntax and the fear evaporates.
@my_decorator
def foo(): ...
Is LITERALLY the same as:
foo = my_decorator(foo)
That's the entire concept. The @ is sugar for 'pass this function to the named callable, replace it with whatever the callable returns'.
my_decorator is a function. It receives foo (the function being decorated) as input. It returns something. Usually that 'something' is a wrapper function — another function that calls foo and adds some behaviour around it. The original 'foo' is now bound to the wrapper.
That's why the same decorator can:
- Time a function (wrap it, log how long it took)
- Cache results (wrap it, return cached value if available)
- Authenticate calls (wrap it, check user before running)
- Register a route (wrap it, add it to a routing table)
- Convert exceptions (wrap it, catch and re-raise)
All of these are 'function in, function out'. Just the wrapper does different things.
Once you internalise this — say it out loud once a day for a week if you have to — every framework you ever read becomes easier. @app.route('/users') in Flask: app.route is a function that returns a decorator that registers the wrapped function in app's routing table. @torch.no_grad(): torch.no_grad is a function that returns a decorator that disables gradient tracking around the wrapped function. Same pattern.
Decorators aren't magic. They aren't a special language feature. They're just function composition with prettier syntax. Internalise that, and Python's biggest source of mystery becomes one of its quieter pleasures.#Python#AI#100DaysOfCode#BuildInPublic#PythonProgramming#Decorators