Python装饰器怎么正确使用
封面图
•
2025-11-10
•
Python
151
0
0
0
Python 装饰器(Decorator)是一种**语法糖**,用于在不修改原函数代码的情况下,**增强函数的功能**。它本质上是一个**接受函数作为参数的函数**,并返回一个新的函数。 --- ## 一、装饰器的基本原理 装饰器本质上是一个函数,它接受一个函数作为参数,并返回一个包装函数。 ```python def my_decorator(func): def wrapper(): print("装饰器前") func() print("装饰器后") return wrapper @my_decorator def say_hello(): print("Hello!") say_hello() ``` **输出:** ``` 装饰器前 Hello! 装饰器后 ``` --- ## 二、装饰器的使用场景 1. **日志记录** 2. **权限验证** 3. **性能测试(计时)** 4. **缓存结果** 5. **事务管理** --- ## 三、带参数的装饰器 如果需要给装饰器传参数,可以使用**嵌套函数**: ```python def repeat(num_times): def decorator(func): def wrapper(*args, **kwargs): for _ in range(num_times): result = func(*args, **kwargs) return result return wrapper return decorator @repeat(3) def greet(name): print(f"Hello, {name}") greet("Alice") ``` **输出:** ``` Hello, Alice Hello, Alice Hello, Alice ``` --- ## 四、类作为装饰器 也可以用类来实现装饰器,通过 `__call__` 方法: ```python 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 say_hi(): print("Hi!") say_hi() ``` **输出:** ``` 装饰器前 Hi! 装饰器后 ``` --- ## 五、保留原函数信息(使用 `functools.wraps`) 使用装饰器时,原函数的元数据(如 `__name__`, `__doc__` 等)会被覆盖。可以使用 `functools.wraps` 来保留这些信息。 ```python from functools import wraps def my_decorator(func): @wraps(func) def wrapper(*args, **kwargs): print("Before function") result = func(*args, **kwargs) print("After function") return result return wrapper @my_decorator def example_function(): """这是一个示例函数""" pass print(example_function.__name__) # 输出: example_function print(example_function.__doc__) # 输出: 这是一个示例函数 ``` --- ## 六、装饰器的组合使用 多个装饰器可以按顺序从下往上应用: ```python @decorator1 @decorator2 def func(): pass ``` 等价于: ```python func = decorator1(decorator2(func)) ``` --- ## 七、常见错误和注意事项 - 不要忘记返回包装函数。 - 如果装饰器本身需要参数,必须用三层嵌套(外层函数接收参数)。 - 使用 `functools.wraps` 可以避免函数元数据丢失。 --- ## 八、总结 | 内容 | 说明 | |------|------| | 装饰器本质 | 函数的函数 | | 语法 | `@decorator` + 函数定义 | | 带参数 | 使用三层嵌套函数 | | 类装饰器 | 使用 `__call__` | | 保留信息 | 使用 `functools.wraps` | --- 如果你有具体的使用场景或问题,欢迎告诉我,我可以帮你写出合适的装饰器代码 😊
上一篇:
python2(中文编码问题):UnicodeDecodeError: 'ascii' codec can't decode byte
下一篇:
VSCode配置Python
标题录入,一次不能超过6条
留言
评论