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 代码更优雅、模块化、易维护! 🚀

浙公网安备 33010602011771号