python---装饰器
文章目录
- 基本概念
- 简单装饰器示例
- 带参数的装饰器
- 内置装饰器
- 多个装饰器
- 保留原函数信息
- 语法糖
装饰器(Decorator)是Python中一种强大的语法特性,它允许你在不修改原函数代码的情况下,为函数添加额外的功能。装饰器本质上是一个高阶函数,它接受一个函数作为参数并返回一个新的函数。
基本概念
装饰器使用@符号表示,放在函数定义的前面:
装饰器被定义的时候,外层函数已经被调用了
@decorator
def function():pass
这等同于:
def function():pass
function = decorator(function)
简单装饰器示例
代码示例1:
def my_decorator(func):print("my_decorator")def wrapper():print("Before function call")func()print("After function call")return wrapper@my_decorator
def say_hello():print("Hello!")
输出1:
my_decorator
代码示例2:
def my_decorator(func):print("my_decorator")def wrapper():print("Before function call")func()print("After function call")return wrapper@my_decorator
def say_hello():print("Hello!")say_hello()
输出2:
my_decorator
Before function call
Hello!
After function call
带参数的装饰器
基本结构介绍:
def decorator_factory(decorator_args): # 外层:接受装饰器参数def decorator(func): # 中层:接受被装饰函数def wrapper(*args, **kwargs): # 内层:执行装饰逻辑# 使用decorator_args和funcreturn func(*args, **kwargs)return wrapperreturn decorator
装饰器本身也可以接受参数:
def repeat(num_times):def decorator_repeat(func):def wrapper(*args, **kwargs):for _ in range(num_times):result = func(*args, **kwargs)return resultreturn wrapperreturn decorator_repeat@repeat(num_times=3)
def greet(name):print(f"Hello {name}")greet("Alice")
输出:
Hello Alice
Hello Alice
Hello Alice
内置装饰器
Python提供了一些有用的内置装饰器:
1、@property - 将方法转换为属性
2、@classmethod - 定义类方法
3、@staticmethod - 定义静态方法
class MyClass:@classmethoddef class_method(cls):print(f"Called class_method of {cls}")@staticmethoddef static_method():print("Called static_method")@propertydef value(self):return self._value@value.setterdef value(self, new_value):self._value = new_value
多个装饰器
多个装饰器的语法是在函数定义前堆叠多个 @decorator:
@decorator1
@decorator2
def my_function():pass
等同于:
my_function = decorator1(decorator2(my_function))
执行顺序
多个装饰器的执行顺序是 从下往上(从最靠近函数的装饰器开始),但实际调用时的执行顺序是 从上往下。
代码示例:
def decorator1(func):print("装饰器1 应用")def wrapper():print("装饰器1 执行前")func()print("装饰器1 执行后")return wrapperdef decorator2(func):print("装饰器2 应用")def wrapper():print("装饰器2 执行前")func()print("装饰器2 执行后")return wrapper@decorator1
@decorator2
def my_function():print("原始函数执行")my_function()
输出信息:
装饰器2 应用
装饰器1 应用
装饰器1 执行前
装饰器2 执行前
原始函数执行
装饰器2 执行后
装饰器1 执行后
保留原函数信息
使用装饰器后,原函数的元信息(如__name__, doc)会被覆盖。
装饰器的代码:
def my_decorator(func):def wrapper(*args, **kwargs):"""Wrapper docstring"""print("Something is happening before the function is called.")return func(*args, **kwargs)return wrapper@my_decorator
def say_hello():"""Say hello docstring"""print("Hello!")print(say_hello.__name__) # 输出: wrapper
print(say_hello.__doc__) # 输出: Wrapper docstring
可以使用functools.wraps来保留:
from functools import wrapsdef my_decorator(func):@wraps(func)def wrapper(*args, **kwargs):"""Wrapper docstring"""print("Something is happening before the function is called.")return func(*args, **kwargs)return wrapper@my_decorator
def say_hello():"""Say hello docstring"""print("Hello!")print(say_hello.__name__) # 输出: say_hello
print(say_hello.__doc__) # 输出: Say hello docstring
语法糖
语法糖是指编程语言中提供的一种语法结构,它不会引入新的功能,但可以让代码更易读、更简洁。
装饰器是语法糖:@decorator 是 Python 提供的一种便捷写法,本质上是高阶函数的应用。使代码更直观、减少代码量、提高可读性。