Master Python Decorators: 10 Advanced Techniques Explained
This article introduces Python decorators, explains their core concept, and walks through ten advanced usage patterns—including parameterized, stacked, class‑based, stateful, memoization, conditional, error‑handling, factory, and method decorators—complete with clear code examples and expected outputs.
What is a decorator?
A decorator is essentially a function or class that wraps another function or class to enhance its behavior.
def my_decorator(func):
def wrapper(*args, **kwargs):
print("调用前")
result = func(*args, **kwargs)
print("调用后")
return result
return wrapper
@my_decorator
def say_hello():
print("Hello!")
say_hello()Output: 调用前 Hello! 调用后
1. Parameterized decorators
You can add an extra outer function to accept arguments for the decorator.
def repeat(times):
def decorator(func):
def wrapper(*args, **kwargs):
for _ in range(times):
result = func(*args, **kwargs)
return result
return wrapper
return decorator
@repeat(3)
def greet(name):
print(f"你好,{name}")
greet("小明")Output: 你好,小明 你好,小明 你好,小明
2. Stacking multiple decorators
Multiple decorators can be applied to a single function; they execute from the bottom up.
def decorator1(func):
def wrapper(*args, **kwargs):
print("decorator1 开始")
result = func(*args, **kwargs)
print("decorator1 结束")
return result
return wrapper
def decorator2(func):
def wrapper(*args, **kwargs):
print("decorator2 开始")
result = func(*args, **kwargs)
print("decorator2 结束")
return result
return wrapper
@decorator1
@decorator2
def say_hi():
print("Hi!")
say_hi()Output: decorator1 开始 decorator2 开始 Hi! decorator2 结束 decorator1 结束
3. Preserving original function metadata with functools.wraps
Decorators normally replace a function’s
__name__and
__doc__; using
functools.wrapsretains them.
from functools import wraps
def my_decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
print("装饰器前置操作")
result = func(*args, **kwargs)
print("装饰器后置操作")
return result
return wrapper
@my_decorator
def say_something():
"""这是一个简单的函数"""
print("说点什么")
print(say_something.__name__) # 输出:say_something
print(say_something.__doc__) # 输出:这是一个简单的函数4. Class‑based decorators
A class can act as a decorator by implementing the
__call__method.
class MyDecorator:
def __init__(self, func):
self.func = func
def __call__(self, *args, **kwargs):
print("类装饰器:调用前")
result = self.func(*args, **kwargs)
print("类装饰器:调用后")
return result
@MyDecorator
def hello():
print("Hello")
hello()5. Stateful (counting) decorators
Decorators can keep state, such as counting how many times a function is called.
def count_calls(func):
def wrapper(*args, **kwargs):
wrapper.calls += 1
print(f"函数 {func.__name__} 被调用了 {wrapper.calls} 次")
return func(*args, **kwargs)
wrapper.calls = 0
return wrapper
@count_calls
def say_hi():
print("Hi!")
say_hi()
say_hi()Output: 函数 say_hi 被调用了 1 次 Hi! 函数 say_hi 被调用了 2 次 Hi!
6. Caching decorator (Memoization)
Cache results of expensive calls to improve performance.
def memoize(func):
cache = {}
def wrapper(*args):
if args not in cache:
cache[args] = func(*args)
return cache[args]
return wrapper
@memoize
def fibonacci(n):
if n <= 1:
return n
return fibonacci(n-1) + fibonacci(n-2)
print(fibonacci(10)) # 输出:557. Conditional decorator
Apply decorator logic only when a condition is met.
DEBUG = True
def debug(func):
def wrapper(*args, **kwargs):
if DEBUG:
print(f"[调试] 正在调用 {func.__name__}")
return func(*args, **kwargs)
return wrapper
@debug
def add(a, b):
return a + b
result = add(3, 5)
print(result)8. Exception‑handling decorator
Wrap a function to catch and report exceptions uniformly.
def handle_error(func):
def wrapper(*args, **kwargs):
try:
return func(*args, **kwargs)
except Exception as e:
print(f"发生错误:{e}")
return wrapper
@handle_error
def divide(a, b):
return a / b
divide(10, 0) # 输出:发生错误:division by zero9. Decorator factory (Factory Pattern)
Generate decorators dynamically, useful for plugin or configurable scenarios.
def make_decorator(prefix=""):
def decorator(func):
def wrapper(*args, **kwargs):
print(f"{prefix}开始执行")
result = func(*args, **kwargs)
print(f"{prefix}结束执行")
return result
return wrapper
return decorator
@make_decorator("【日志】")
def say_hello():
print("Hello")
say_hello()10. Class method / static method decorators
Decorators can also be applied to class methods and static methods.
class MyClass:
@classmethod
def class_method(cls):
print("这是类方法")
@staticmethod
def static_method():
print("这是静态方法")
MyClass.class_method()
MyClass.static_method()Test Development Learning Exchange
Test Development Learning Exchange
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.