装饰器的本质:将原函数封装到另一个函数体内。
def outer(func): #func = 原来的f1函数 def inner(): print("hello") print("hello") print("hello") #以上为f1原来的函数 r = func() #r = None print ("end") print ("end") print ("end") return r return inner //返回的是这个函数的内存。相当于执行inner @outer def f1(): print ("F1")
以下为此装饰器的流程:
1.执行outer函数,并将其下的函数名,当做参数
2.将outer的返回值重新赋值给f1 = outer的返回值
(实际上@outer def f1():就等于 def outer中的inner函数。)
#新的f1函数 = inner
执行f1()
PS:因为inner这个函数并没有原来的f1的返回值。所以我们用r来接收f1的返回值。并且将r作为inner的返回值。
装饰器的目的:在不改变原函数的基础上,修改原函数。
只要函数应用装饰器,那么函数就会被重新定义,重新定义为装饰器的内层函数。
以上代码中原函数并没有参数,实际情况下原函数可能会有参数代入。同时存在不统一的参数个数。这个时候采用以下*arg 和 **kwargs。放入inner函数中。
arg是一个元组。kwargs是一个空字典。
def outer(func): def inner(*arg,**kwargs): print ("123") ret = func(*arg,**kwargs) print ("456") return ret return inner @outer def index(a1,a2): print ("非常复杂") return a1+a2
一个函数可以运用多个装饰器:
def outer_0(func): def inner(*arg,**kwargs): print ("3.5") ret = func(*arg,**kwargs) return ret return inner def outer(func): def inner(*arg,**kwargs): print ("123") ret = func(*arg,**kwargs) print ("456") return ret return inner @outer_0 @outer def index(a1,a2): print ("非常复杂") return a1+a2 index(1,2)
输出结果:
PS:@outer_0调用的inner函数中的func实际上是第二个@outer的inner函数。outer的inner函数调用的才是index()函数
@outer def f1()结合就是一个新的index函数。也就是等于outer里面的inner函数。这个整体在用@outer_0装饰,就将outer的inner赋值进去