Fundamentals 7 min read

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.

Test Development Learning Exchange
Test Development Learning Exchange
Test Development Learning Exchange
Master Python Decorators: 10 Advanced Techniques Explained

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.wraps

retains 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))  # 输出:55

7. 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 zero

9. 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()
PythonProgrammingsoftware engineeringTutorialdecoratorcodeadvanced
Test Development Learning Exchange
Written by

Test Development Learning Exchange

Test Development Learning Exchange

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.