对装饰器接触过的同学都知道,一般写装饰器的时候会定义一个内部的wrapper函数
def decorate(func): # 传入函数名当然是因为python处处皆是对象
def wrapper(a, b):
print('*'*30)
return func(a, b)
return wrapper
@decorate
def add(a, b):
return a + b
if __name__ == '__main__':
print(add(1, 2))
输出
******************************
3
如果这么写,不去调用add函数
def decorate(func):
print('run')
def wrapper(a, b):
print('*'*30)
return func(a, b)
return wrapper
@decorate
def add(a, b):
return a + b
# if __name__ == '__main__':
# print(add(1, 2))
输出
run
所以这里必须定义内部函数,这属于python的闭包
而且为什么是return wrapper而不是return wrapper()?
return wrapper可以理解为返回wrapper函数的指针
返回给add方法,在调用add方法的时候相当于执行了wrapper方法,所以wrapper也需要和add方法传入同样的参数
如果不传参:
def decorate(func):
def wrapper():
print('*'*30)
return func()
return wrapper
@decorate
def add(a, b):
return a + b
if __name__ == '__main__':
print(add(1, 2))
它报的错是wrapper函数需要参数
TypeError: wrapper() takes 0 positional arguments but 2 were given
而且不调用add方法的时候wrapper也不会被执行(因为返回的仅仅是指针)
如果
print(add.__name__)
输出
wrapper
当然如果想参数传递更通用,可以
def decorate(func):
def wrapper(*args, **kwargs):
print('*'*30)
return func(*args, **kwargs)
return wrapper
网友评论