装饰器参数之谜
之前已经初步了解过装饰器了,知道了装饰器可以“偷梁换柱”,在不改变函数的调用方式和函数内容的时候,而把函数的功能偷偷地修改。
那么问题来了,如果被修改的函数中有参数的话,怎么样去写这个装饰函数呢?Ok,废话不多说,先上程序:
def func(bar):
def dec():
bar()
print("this is dec")
return dec
@func #test1 = func(test1)
def test1(name):
print("this is test1 and I'm",name)
test1()
很显然,程序会报错:
in dec bar()
TypeError: test1() missing 1 required positional argument: 'name'
报错说test1()缺少位置参数'name',ok,我们来看程序,首先@func中,func(bar)中执行的是: bar = test1,func()中的内容并没有执行,然后就将dec作为返回值返回,此时,相当于执行了:test1 = dec,然后给test1加了个(),也就是调用text1(),那么其实就是相当于调用的是dec,也就是dec(),那么把参数放到dec中就OK了,也就是dec(name),当然,下面跟着执行的bar()其实是执行test1(),给他括号中也添加上name就可以了。问题解决。如下:
def func(bar):
def dec(name):
bar(name)
print("this is dec")
return dec
@func #test1 = func(test1)
def test1(name):
print("this is test1 and I'm",name)
test1("Jack")
输出:
this is test1 and I'm Jack
this is dec
OK,问题2,如果被装饰的函数有好多个呢?其中有的函数不需要参数,有的函数需要3个,有的函数需要9个,这样的话,同一个装饰器装饰不同的函数肯定是会报错的,因为不同的函数的参数是不同的。那么如何解决呢?这里有一个非固定参数的表示办法,有参数你就传进来,没参数就不用你传,也不会报错。是不是很棒?程序如下:
def func(bar):
def dec(*args,**kwargs):
bar(*args,**kwargs)
print("this is dec")
return dec
@func #test1 = func(test1)
def test1(name):
print("this is test1 and I'm",name)
@func
def test2():
print("this is test2")
test1("Jack")
test2()
输出为:
this is test1 and I'm Jack
this is dec
this is test2
this is dec
是不是很方便,并且不管你需要装饰的函数有多少参数都无所谓,这个统统包容。