引言
装饰器不仅是 Python 中最具魔力的语法之一,也是一种优雅处理函数逻辑增强的方式。本文将通过练手项目为例,带你吃透它的本质与用法。
什么是 Decorator(装饰器)?
装饰器本质上是一个“接收函数并返回新函数”的函数。
你可以把它想象成给函数加上“拦截器”,在不修改原函数代码的前提下,对其行为进行增强、包装、控制等操作。
实例入门:一个简单的装饰器
下面是一个最基础的装饰器
def my_decorator(func):
def wrapper(*args, **kwargs):
print("begin call")
print("i guess params is", args, 'and', kwargs)
print("i want to change it")
# tuple 不可变,需要转为 list 再修改
args = list(args)
args[0] = "ALC"
kwargs['what'] = 'a command'
result = func(*args, **kwargs)
print("after call")
return result
return wrapper
@my_decorator
def my_function(who: str, what: str):
print(who, "Called", what)
调用这个方法:my_function("zunmx", what="a function")
输出结果:
begin call
i guess params is ('zunmx',) and {'what': 'a function'}
i want to change it
ALC Called a command
after call
我们可以看到,my_function 本身并没有改变,但它的行为被我们“劫持”并注入了新逻辑。这就是装饰器的核心威力。
带参数的装饰器
比如你想要一个函数执行多次怎么办?再写三行 for ?不优雅。用装饰器!
def repeat(times):
def decorator(func):
def wrapper(*args, **kwargs):
for _ in range(times):
func(*args, **kwargs)
return wrapper
return decorator
使用方式:
@repeat(3)
def hello_zunmx():
print("hello zunmx")
执行hello_zunmx()
输出:
hello zunmx
hello zunmx
hello zunmx
非常自然,就像你定义了一个新语法一样。
多个装饰器叠加
@decorator1
@decorator2
def func():
pass
等价于:
func = decorator1(decorator2(func))
这允许我们构建类似“中间件链”的结构,在 Web 框架中大量使用。
✅ 保留函数原信息(使用 functools.wraps)
装饰器默认会把原函数的名字、注释等覆盖掉,可以使用 @wraps(func) 保留:
from functools import wraps
def deco(f):
@wraps(f)
def wrapper(*args, **kwargs):
return f(*args, **kwargs)
return wrapper
装饰器可以做什么?
- 权限控制(权限注解)
- 缓存(如 @lru_cache)
- 异常捕获(如 retry 装饰器)
- 日志记录(自动打印调用信息)
- 计时器(性能分析)
- ......
结论
Python 装饰器初看可能有点“绕”,但当你掌握了其本质,可以少些很多代码,并且解耦,让方法更加“健壮”


评论 0
还没有评论,来说点什么吧。