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()#正常調用
相關文章
相關標籤/搜索