pin_drop当前位置:知识文库 ❯ 图文

Python装饰器进阶 - 带参数装饰器与类装饰器

概述

在掌握装饰器基础后,进阶内容包括带参数的装饰器、functools.wraps保留元信息、类装饰器和多个装饰器叠加使用。这些高级技巧让装饰器更加强大和实用。

语法

代码示例

@decorator(arg)
def func():
    pass

带参数的装饰器

代码示例

def repeat(n):
    def decorator(func):
        def wrapper(*args, **kwargs):
            for _ in range(n):
                result = func(*args, **kwargs)
            return result
        return wrapper
    return decorator

@repeat(3)
def say_hello(name):
    print(f"Hello, {name}!")

say_hello("Alice")

functools.wraps

代码示例

from functools import wraps

def my_decorator(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        return func(*args, **kwargs)
    return wrapper

@my_decorator
def my_function():
    """这是我的函数"""
    pass

print(my_function.__name__)
print(my_function.__doc__)

类装饰器

代码示例

class CountCalls:
    def __init__(self, func):
        self.func = func
        self.count = 0
    
    def __call__(self, *args, **kwargs):
        self.count += 1
        print(f"调用次数: {self.count}")
        return self.func(*args, **kwargs)

@CountCalls
def say_hello():
    print("Hello!")

say_hello()
say_hello()

注意事项

提示:带参数的装饰器需要三层嵌套函数。functools.wraps保留原函数的元信息。类装饰器通过__call__方法实现。多个装饰器从下到上依次执行。

小结

  • 带参数的装饰器需要三层嵌套函数

  • functools.wraps保留原函数的元信息

  • 类装饰器通过__call__方法实现

  • 多个装饰器从下到上依次执行

练习题

练习1

编写装饰器retry(n)失败时重试n次

练习2

编写类装饰器Singleton实现单例模式

常见问题

带参数的装饰器为什么需要三层嵌套?

第一层接收装饰器参数,第二层接收被装饰的函数,第三层是实际的包装函数。三层结构分别对应不同层级的参数传递需求。

functools.wraps的作用是什么?

functools.wraps用于保留原函数的元信息,如函数名、文档字符串等。如果不使用wraps,被装饰后的函数会显示wrapper的信息而非原函数信息。

类装饰器和函数装饰器有什么区别?

类装饰器通过实现__call__方法来工作,可以保持状态信息(如调用次数),而函数装饰器通常依赖闭包变量来保持状态。类装饰器在需要维护复杂状态时更有优势。

多个装饰器的执行顺序是怎样的?

多个装饰器从下到上依次执行装饰过程,但实际调用时从上到下依次执行。理解这一顺序对于正确使用多层装饰非常重要。

标签: 装饰器 functools.wraps 类装饰器 高级技巧 Python进阶

本文涉及AI创作

内容由AI创作,请仔细甄别

list快速访问

上一篇: Python装饰器 - 函数功能扩展技巧 下一篇: Python递归函数 - 阶乘与斐波那契数列

poll相关推荐