Loading lessons...
Decorators
Decorators
A decorator takes a function and wraps it with extra behavior, without changing the function's own code.
Functions are values
In Python you can pass a function like any value:
def hello():
print("Hello")
say = hello
say() # Hello
A simple decorator
def decorator(func):
def wrapper():
print("Before the call")
func()
print("After the call")
return wrapper
def say_hello():
print("Hello!")
say_hello = decorator(say_hello)
say_hello()
# Before the call
# Hello!
# After the call
The @ syntax
The @ symbol applies a decorator cleanly:
@decorator
def say_hello():
print("Hello!")
This is exactly the same as say_hello = decorator(say_hello).
Decorators with arguments
def log(func):
def wrapper(*args, **kwargs):
print(f"Calling {func.__name__}")
return func(*args, **kwargs)
return wrapper
@log
def add(a, b):
return a + b
print(add(2, 3)) # Calling add then 5
Common uses
- Logging and timing
- Access control (require login)
- Caching results
- Framework features (routes in Flask/Django)
TL;DR
- Decorators wrap functions with extra behavior.
@nameis sugar forfunc = name(func).- The wrapper receives
args, *kwargsand calls the original. - Used for logging, checks, and caching.