Python Decorators
A decorator transforms or wraps a function when it is defined. It is useful for a consistent cross-cutting behaviour, provided the wrapper keeps a clear contract.
Understand the idea
The @ syntax passes the function into the decorator and binds the returned callable to its name. functools.wraps preserves helpful metadata such as the original name and docstring. Forward *args and **kwargs correctly, return the wrapped result, and do not swallow exceptions unless handling them is part of the documented policy.
Where to try it
Open this example with Try in playground. The code loads as editable text and does not run until you select Run. The first run downloads Python. Each run starts fresh; temporary files created by a script are not files on your PC.
A worked example
from functools import wraps
def announce(function):
@wraps(function)
def wrapper(*args, **kwargs):
print("Starting", function.__name__)
return function(*args, **kwargs)
return wrapper
@announce
def add(a, b):
return a + b
print(add(2, 3))
Read the result
The output announces add and then prints 5. The wrapper returns the calculation rather than replacing it with None.
Try one change
Decorate another function taking a keyword argument and verify that its result and name are preserved.