Python装饰器

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()#正常调用