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