python装饰器很是的强大,装饰器能够在不修改原代码的状况下,为函数添加新的功能,这也适应了开发的模式。要了解装饰器,首先要明白函数的调用方式。咱们知道函数名就是函数的地址,地址+()就是调用这个函数。python
1.函数的调用ide
函数名+()就是调用这个函数函数
def food(): print("food") food#不会调用,food是food函数的地址 food()#调用
2.函数做为参数ui
既然函数名是一个地址,那么咱们可不能够把这个地址做为参数传进另一个函数再调用呢code
def food(func):#给food函数增长一个形参 print("food") func()#在此处调用func即传进来的fruit函数 def fruit(): print("fruit") food(fruit)#把函数名传进另外一个函数
那么这和装饰器有什么关系?装饰器就是利用函数即变量这一律念,把要装饰的函数传进另一个函数进行调用,而且在另外的函数上再添加新的功能。开发
3.简单的装饰器it
def decorator(func): def inside(): func()#在内部调用传进来的函数 print("inside")#新的功能 return inside#返回的是函数地址 def food(): print("food") food=decorator(food)#把food传进去,返回的地址赋值给food,函数即变量,能够赋值给一个变量 food()#调用返回的函数
在decorator函数嵌套一个函数inside,在inside中调用传进来的函数,可是咱们不直接调用,而是返回了inside的地址,在外面定义一个变量接收他的地址,而后调用。这就是装饰器,food()已经不是原来的food函数了,是一个通过decorator装饰的函数。在python中,装饰器有本身的写法,就是用@+函数名class
def decorator(func): def inside(): func()#在内部调用传进来的函数 print("inside")#新的功能 return inside#返回的是函数地址 @decorator#等价于food=decorator(food) def food(): print("food") food()#调用返回的函数
那么若是被修饰的函数带有参数怎么办?变量
4.被修饰的函数带有参数装饰器
当被修饰的函数带有参数,那么这个参数会传给inside函数,而且能够调用这些参数
def decorator(func): def inside(a,b):#再这里接收被修饰函数的参数 func(a,b)#在内部调用传进来的函数 print("sum=",a+b)#内部调用传进来的参数 print("inside")#新的功能 return inside#返回的是函数地址 def food(a,b): print("food") food(1,2)#调用返回的函数
若是装饰函数和被装饰函数都带有参数怎么办?
5.装饰函数带有参数
装饰函数带有参数时,被修饰函数就不能再传给最外层函数了,但能够往里面一层传,也就是能够在装饰函数再继续嵌套函数。
def decorator(dec1,dec2):#decorator本身的参数 def outside(func):#被修饰的函数 def inside(a,b):#被修饰函数的参数 func()#调用 print("sum=",a+b)#使用被修饰函数的参数 print("from decorator:",dec1+dec2)#decorator自己的参数 return inside#返回地址 return outside#返回 @decorator(1,2)#decorator的参数 def food(a,b): print("food") food()#food函数的调用方式没有改变
6.一个函数被多个装饰器修饰
一个函数是能够被多个装饰器装饰的,只需在函数名上加上@+函数名
def decorator1(func): def inside(): func() print("from decorator1") return inside def decorator2(func): def inside(): func() print("from decorator2") return inside #多个装饰器,等价于food=decorator2(decorator1(food)) @decorator2 @decorator1 def food(): print("from food") food()#正常调用