装饰器与闭包
闭包
内层函数引用外层变量,外层返回内层函数:
def make_adder(n):
def add(x):
return x + n
return add
add10 = make_adder(10)
print(add10(5)) # 15
函数装饰器
装饰器本质是「接收函数、返回函数」的高阶函数:
import functools
def log_call(fn):
@functools.wraps(fn)
def wrapper(*args, **kwargs):
print(f"call {fn.__name__}")
return fn(*args, **kwargs)
return wrapper
@log_call
def add(a, b):
return a + b
print(add(1, 2))
@log_call 等价于 add = log_call(add)。
functools.wraps 用于保留原函数的名字与文档字符串。
带参数的装饰器(直觉)
先写一层「接收装饰器参数」的外函数,再返回真正的装饰器。入门阶段能读懂无参装饰器即可;复杂元编程可后置。
要点
- 闭包保存外层状态
- 装饰器用于统一加日志、计时、校验等横切逻辑
- 记得
functools.wraps