python_3 装饰器参数之谜

装饰器参数之谜

之前已经初步了解过装饰器了,知道了装饰器可以“偷梁换柱”,在不改变函数的调用方式和函数内容的时候,而把函数的功能偷偷地修改。
那么问题来了,如果被修改的函数中有参数的话,怎么样去写这个装饰函数呢?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

是不是很方便,并且不管你需要装饰的函数有多少参数都无所谓,这个统统包容。

猜你喜欢

转载自www.cnblogs.com/zhqin/p/9949794.html