Master Python Decorators: From Simple 2‑Layer to Powerful 3‑Layer Patterns
This article explains Python decorators, describing how they wrap functions to add extra behavior, demonstrates a basic two‑layer decorator with code examples, then extends to parameterized three‑layer decorators, and shows real‑world uses in Flask and Django for routing and access control.
In Python, a decorator "decorates" a function object, meaning it adds extra functionality that is not part of the core logic, such as measuring execution time with the time module or letting Django determine whether a view handles GET or POST requests.
Types of decorators
Decorator without parameters (2 layers)
Decorator with parameters (3 layers)
The terms "2 layers" and "3 layers" are the author’s own naming convention to help remember the concepts.
Decorator without parameters (2 layers)
<code>def simple_decorator(func):
def wrapper(name):
print("Before the function call")
say = func(name)
print("After the function call")
return say
return wrapper
@simple_decorator
def say_hello(name):
print("Function being executed")
return f"Hello {name}!"
print(say_hello('Rohit'))
</code>Output:
<code>Before the function call
Function being executed
After the function call
Hello Rohit!
</code>This shows how additional statements can be executed before and after the original function, similar to middleware in web frameworks or custom validation logic.
The outer function ( simple_decorator(func) ) receives the original function, while the inner function ( def wrapper(name) ) receives the function’s arguments. The wrapper runs the original function and any extra code, returning the result.
Decorator with parameters (3 layers)
In production software, parameterized decorators are widely used, especially in popular web frameworks for routing and access control.
<code>@app.route('/user/<int:user_id>')
def user_profile(user_id):
return f"User ID is {user_id}"
@permission_required('app_name.can_view_dashboard', login_url='/login/')
def dashboard_view(request):
return render(request, 'dashboard.html')
</code>The following example demonstrates a three‑layer decorator that repeats the original function three times.
<code>def repeat_decorator(times):
def decorator(func):
def wrapper(name):
for _ in range(times):
print("Before the function call")
result = func(name)
print("After the function call")
return result
return wrapper
return decorator
@repeat_decorator(times=3)
def say_hello(name):
print("Function being executed")
return f"Hello {name}!"
print(say_hello('Rohit'))
</code>Output:
<code>Before the function call
Function being executed
After the function call
Before the function call
Function being executed
After the function call
Before the function call
Function being executed
After the function call
Hello Rohit!
</code>The outermost layer controls how many times the function runs, while the inner layers handle the actual execution and additional logic.
Summary
This article explored the concept of Python decorators and how they can extend existing functions. It started with basic two‑layer decorators, then moved to more advanced three‑layer, parameterized examples, and showed real‑world usage in Flask and Django for routing and access control. The provided code snippets serve as a foundation for creating custom decorators.
Code Mala Tang
Read source code together, write articles together, and enjoy spicy hot pot together.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.