装饰器(Decorator)是 Python 中一种高级特性,它允许程序员修改或增强函数和方法的行为,而无需直接更改其源代码。装饰器本质上是一个返回函数的高阶函数,它可以接收一个函数作为参数,并返回一个新的或修改后的函数。通过使用装饰器,您可以实现诸如日志记录、访问控制、性能测量等功能,同时保持代码的清晰和模块化。
装饰器的工作原理
装饰器定义:首先,您需要定义一个装饰器函数。这个函数接受一个被装饰的函数作为参数,并返回一个新的函数(通常是内部定义的一个闭包),该新函数可以在执行原始函数之前或之后添加额外逻辑。
应用装饰器:要将装饰器应用于某个函数,可以使用 @decorator_name 语法糖,放在函数定义之前。这相当于在函数定义后立即调用装饰器并将函数作为参数传递给它。
执行流程:当调用被装饰的函数时,实际上是在调用装饰器返回的新函数。这意味着您可以在实际执行目标函数之前或之后插入自定义行为。
示例:基本装饰器
在这个例子中,my_decorator 是一个简单的装饰器,它包装了 say_hello 函数,在调用前后打印消息。
带参数的装饰器
有时,您可能希望装饰器本身也能接受参数。为了实现这一点,可以创建一个“装饰器工厂”——即一个返回装饰器的函数。
示例:带参数的装饰器
这里,repeat 是一个装饰器工厂,它根据提供的 num_times 参数生成一个具体的装饰器。
类装饰器
除了函数,Python 还支持类装饰器。类装饰器通常用于修改类的行为或属性。它们接收类作为参数,并返回一个新的类或修改后的类。
示例:类装饰器
在这个例子中,add_method 是一个类装饰器,它向 MyClass 动态添加了一个新的方法。
内置装饰器
Python 提供了一些内置的装饰器来简化常见的编程任务:
@classmethod 和 @staticmethod:用于定义类方法和静态方法。
@property:用于将类的方法转换为只读属性。
@functools.lru_cache:用于缓存函数的结果以提高性能。
@dataclasses.dataclass:用于自动为类生成特殊方法(如 __init__() 和 __repr__())。
示例:使用 @property
使用多个装饰器
如果一个函数被多个装饰器修饰,则这些装饰器按照从下到上的顺序依次应用。也就是说,最接近函数定义的装饰器最先执行。
示例:多个装饰器
在这个例子中,decorator_two 首先被应用,然后是 decorator_one。
总结
装饰器是 Python 中非常强大且灵活的工具,它们可以让您以优雅的方式扩展或修改函数和类的功能。通过理解装饰器的工作原理以及如何构建自己的装饰器,您可以编写出更加简洁、可维护和功能丰富的代码。随着经验的积累,您还将发现更多关于装饰器的高级用法和最佳实践。