python裝飾器基礎及應用

一、簡介

裝飾器是是修改其它函數功能的函數;其意義是讓其他函數在不修改任何代碼的前提下增加額外功能

 

 

二、數據類型

 

首先我們來看一段簡單的代碼:

from types import MethodType,FunctionType

class A(object):
    def f1(self):
        pass


def f2(a, b):
    return a + b

if __name__ == '__main__':
    a = A()
    print(type(a.f1))   #<class 'method'>
    print(type(f2))    #<class 'function'>

結論:不難看出,f1的類型是方法,f2的類型是函數;那有人會問了解這個有啥作用呢?其實了解這個有助於我們下面了解裝飾器的原理

 

 

三、認識裝飾器:

 

let’s go… 我們來看一個案例:

def B():
    print("now you are inside the B() function")
    
    
    def sing():
        return "now you are in the sing() function"
    
    
    def eat():
        return "now you are in the eat() function"
    
    
    def sleep():
        return "now you are in the sleep() function"
    
    print(sing())
    print(eat())
    print(sleep())
#輸出的結果為:
now you are inside the hi() function
now you are in the sing() function
now you are in the eat() function
now you are in the sleep() function

 

結論:那現在我們知道了可以在函數中定義另外的函數。也就是說:我們可以創建嵌套的函數

 

我們再接着看一段代碼,如何讓函數作為參數傳給另外一個函數的:

def A():
    return "hi 小陳!"

def doSomethingBeforeA(func):
    print("I am doing some boring work before executing A()")
    print(func())

#執行:
doSomethingBeforeA(A)
#輸出結果:
I am doing some boring work before executing A()
hi 小陳!

 

 

 什麼?你還沒看懂,那我們再看一個案例:

 

from types import FunctionType

def text():
    return "Hello world!"

def add_itali(func: FunctionType):
    def new_func():
        #print("now you are in the new_func() function")
        return text()   #返回text()函數
    return new_func

#執行:
print(type(add_itali(text)))  
print(add_itali(text)())  
#輸出結果:
<class 'function'>
Hello world!

 

難么現在你看懂了么?如果還是沒懂,沒關係我們再來看看下一段代碼:

def new_decorator(func):
    def wrapTheFunction():
        print("I am doing some boring work before executing func()")
        func()
        print("I am doing some boring work after executing func()")
    return wrapTheFunction

def requiring_decoration():
    print("I am the function which needs  decoration")


#執行:
requiring_decoration()

#輸出結果:
I am the function which needs  decoration
#執行:
new_decorator(requiring_decoration)()

#輸出結果:
I am doing some boring work before executing func()
I am the function which needs  decoration
I am doing some boring work after executing func()

有人會有疑問,new_decorator(requiring_decoration)()為哈後面要加「()」呢去,請繼續往下看:

#執行:
print(new_decorator(requiring_decoration))

#輸出結果:
function new_decorator.<locals>.wrapTheFunction at 0x000001FC976BB620>

為什麼會這樣呢,請隨我娓娓道來。。。

 

 

 

四、裝飾器的優雅使用:

 

那麼好,我們把上面代碼再優化下,用裝飾器常用的表達方式表示出來:

def new_decorator(func):
    def wrapTheFunction():
        print("I am doing some boring work before executing func()")
        func()  #被裝飾的函數
        print("I am doing some boring work after executing func()")
    return wrapTheFunction

@new_decorator
def requiring_decoration():
    print("I am the function which needs  decoration")
#執行:
requiring_decoration()

#輸出結果:
I am doing some boring work before executing func()
I am the function which needs  decoration
I am doing some boring work after executing func()

老鐵們,現在你們懂了么,沒懂我們再來看一段代碼:

#需求:  <b><i> Hello World!</i></b>
from types import FunctionType
def add_bold(func: FunctionType): def new_func(): return f"<b>{func()}</b>" return new_func def add_itali(func: FunctionType): def new_func(): return f"<i>{func()}</i>" return new_func @add_itali # 語法 @add_bold def text(): return "Hello world!"
#執行:
print(text())

#輸出結果:
<i><b>Hello world!</b></i>

 

 

五、總結:

 

#語法:裝飾器就是一個函數
def 裝飾器名(func):
      def wrapper(*args, **kwargs):
             // 要做的裝飾 ,,省略若干代碼
             result = func(*args,**kwargs)
             return result
      return wrapper