Python 的装饰器(Decorator)就是出现在函数声明上方以 @ 开头的语句,如下所示:
@log
def now():
print('2024-08-07')这种语句可以拓展函数的功能,就像“装饰”了原本的函数一样,所以被称为装饰器。
而实际上它是一个语法糖,当我们调用 now() 的时候,实际上是调用了:
# now()
log(now)()所以总的来说,实际调用的,其实是以 now 为参数(函数式编程)构造出的一个新函数,而非 now 了,更具体一些, log 可以实现成这个样子:
def log(func):
def wrapper(*args, **kw):
print('call %s():' % func.__name__)
return func(*args, **kw)
return wrapper这是一种Python Closure的手法, wrapper 捕获了外部变量 func ,实际调用的是 wrapper ,而 wrapper 的效果是先打印一句 call funcname ,然后再调用 now 。此时调用 now() 的效果如下:
call now():
2024-08-07更进一步,装饰器是可以有参数的,比如这种:
@log('execute')
def now():
print('2024-6-1')这种语法糖的本质是:
# now()
log('execute')(now)()因此,此时 log 会在外面多一层,用于接收装饰器参数:
def log(text):
def decorator(func):
def wrapper(*args, **kw):
print('%s %s():' % (text, func.__name__))
return func(*args, **kw)
return wrapper
return decorator闭包分别捕获了 text 和 func 。