python中的装饰器
Python中的装饰器(Decorator)
1. 什么是装饰器?
装饰器(Decorator)是 Python 中的一种高级函数功能,它允许在不修改原函数代码的情况下,动态地增强或修改函数的功能。常用于日志记录、权限验证、函数执行时间计算、缓存等场景。
装饰器本质上是一个高阶函数:
- 接受一个函数作为输入,并返回一个新的增强版函数。
- 使用
@decorator_name
语法糖,可以简洁地应用装饰器。
2. 最简单的装饰器
def my_decorator(func): def wrapper(): print("函数执行前") func() print("函数执行后") return wrapper @my_decorator def say_hello(): print("Hello, World!") say_hello()
执行结果
函数执行前 Hello, World! 函数执行后
解析
my_decorator
接收say_hello
,返回wrapper
,替换原函数。wrapper
在say_hello
前后增加了额外的功能。@my_decorator
等价于say_hello = my_decorator(say_hello)
。
3. 带参数的装饰器
如果被装饰的函数有参数,wrapper
需要支持 *args
和 **kwargs
:
def my_decorator(func): def wrapper(*args, **kwargs): print("执行前") result = func(*args, **kwargs) print("执行后") return result return wrapper @my_decorator def add(a, b): return a + b print(add(3, 5))
执行结果
执行前 执行后 8
4. 带参数的装饰器(装饰器本身接受参数)
如果希望控制装饰器行为,可以再封装一层:
def repeat(n): def decorator(func): def wrapper(*args, **kwargs): for _ in range(n): func(*args, **kwargs) return wrapper return decorator @repeat(3) def say_hello(): print("Hello!") say_hello()
执行结果
Hello! Hello! Hello!
5. 使用 functools.wraps
保留原函数信息
装饰器会修改原函数的 __name__
和 __doc__
,使用 functools.wraps
解决:
import functools def my_decorator(func): @functools.wraps(func) def wrapper(*args, **kwargs): print("执行前") result = func(*args, **kwargs) print("执行后") return result return wrapper @my_decorator def my_function(): """这是我的测试函数""" print("执行 my_function") print(my_function.__name__) # 仍然是 "my_function" print(my_function.__doc__) # 仍然是 "这是我的测试函数"
6. 类装饰器
装饰器也可以用类来实现:
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 greet(name): print(f"Hello, {name}!") greet("Alice")
执行结果
执行前 Hello, Alice! 执行后
7. 多个装饰器嵌套
多个装饰器按从下到上的顺序应用:
def decorator1(func): def wrapper(*args, **kwargs): print("装饰器1") return func(*args, **kwargs) return wrapper def decorator2(func): def wrapper(*args, **kwargs): print("装饰器2") return func(*args, **kwargs) return wrapper @decorator1 @decorator2 def hello(): print("Hello, world!") hello()
执行结果
装饰器1 装饰器2 Hello, world!
8. 实际应用场景
(1)日志记录
装饰器可用于自动记录函数调用:
def log(func): def wrapper(*args, **kwargs): print(f"调用 {func.__name__},参数:{args}, {kwargs}") result = func(*args, **kwargs) print(f"返回值:{result}") return result return wrapper @log def multiply(a, b): return a * b print(multiply(3, 4))
执行结果
调用 multiply,参数:(3, 4), {} 返回值:12 12
(2)权限控制
常用于 检查用户权限:
def require_permission(role): def decorator(func): def wrapper(*args, **kwargs): if role != "admin": print("权限不足") return return func(*args, **kwargs) return wrapper return decorator @require_permission("user") def delete_data(): print("数据已删除") delete_data()
执行结果
权限不足
(3)计算函数执行时间
import time def timer(func): def wrapper(*args, **kwargs): start = time.time() result = func(*args, **kwargs) end = time.time() print(f"{func.__name__} 执行时间:{end - start:.5f} 秒") return result return wrapper @timer def slow_function(): time.sleep(2) print("函数执行完成") slow_function()
执行结果
函数执行完成 slow_function 执行时间:2.00012 秒
(4)缓存函数结果
使用 functools.lru_cache
可缓存计算结果,提升性能:
import functools @functools.lru_cache(maxsize=3) # 最多缓存3个结果 def fib(n): if n < 2: return n return fib(n-1) + fib(n-2) print(fib(10))
加速递归计算斐波那契数列。
总结
场景 | 作用 |
---|---|
日志 | 记录函数调用信息 |
权限控制 | 限制非管理员访问 |
性能分析 | 计算函数运行时间 |
缓存 | 加速计算(如 Fibonacci) |
重试机制 | 失败后自动重试 |
掌握装饰器可以让 Python 代码更优雅、模块化、易维护! 🚀
本文作者:清澈的澈
本文链接:https://www.cnblogs.com/lmc7/p/18703470
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步