1.裝飾器定義和原則python
定義:裝飾器本質是一個函數,(裝飾其它函數)就是爲其它函數添加附加功能。app
原則:不能修改被裝飾函數的源代碼;不能修改被裝飾函數的調用方式。ide
2.實現裝飾器知識儲備函數
1.函數即變量this
2.高階函數spa
a.把一個函數名當作實參傳給另外一個函數--》能夠實現不修改被裝飾函數的源代碼,爲其它函數添加附加功能ip
import time def test1(): time.sleep(3) print("this is test1") def test2(func): start_time = time.time() func() stop_time = time.time() print("this func run time is %s"%(stop_time-start_time)) test2(test1)
b.返回值中包含函數名-->能夠實現不修改被裝飾函數的調用方式內存
def test3(): print("this is test3") def test4(func): print("附加功能") return func test3 = test4(test3) test3()
注:調用函數的時候不加括號表示調用該函數內存地址如:print(test3)--><function test3 at 0x003E7660>,加括號表示執行該函數input
3.嵌套函數 ,在一個函數裏再次聲明一個函數it
def test5(): print("this is test5") def test6(): #相似於局部變量,只能在局部調用 print("this is test6") test6() test5()
4.高階函數+嵌套函數--》裝飾器
a.裝飾器舉例1
import time #裝飾器:增長計算函數運行時間的功能 def timer(func): def deco(*args,**kwargs): #在裝飾器中增長*args,**kwargs以後,不管原函數參數的個數是多少,均可以適應 start_time = time.time() res = func(*args,**kwargs) stop_time = time.time() print("this func run time is %s"%(stop_time-start_time)) return res #在裝飾器中增長return res以後,能夠返回原函數中的返回值 return deco #下面的1,2也就是裝飾器執行的過程 #原函數 @timer #一、 @timer 其實是在執行「test1 = timer(test1)」-->將原test1 內存地址傳給func,而後直接將deco的內存地址返回到test1 def test1(): time.sleep(3) print("this is test1") #test1 = timer(test1) test1() #二、這時test1()至關於直接調用deco(*args,**kwargs),而deco裏的func仍是指向的原test1的內存地址 @timer def test2(name): time.sleep(1) print("this is %s"%(name)) test2("fengxiaoli") @timer def test3(name): time.sleep(2) print("this is %s"%(name)) return "test3 res" print(test3("cx")) #先執行test3(cx),再打印test3的返回結果
b.裝飾器舉例2
#給網頁增長一個驗證的功能,而且home頁面用本地驗證,bbs頁面用ldap驗證 user = "fengxiaoli" passwd = "123456" def auth(auth_type): def out_wrapper(func): def wrapper(*args,**kwargs): if auth_type == "local": user_name = input("請輸入用戶名:").strip() password = input("請輸入密碼:").strip() if user_name == user and password == passwd: res = func(*args,**kwargs) print("welcome to home!") return res else: print("用戶名或密碼錯誤") else: print("ldap login") return wrapper return out_wrapper #原函數 def index(): print("this is index") @auth(auth_type="local") #相對於裝飾器1中的例子,這裏調用裝飾器的時候使用了參數,在1中裝飾器不變得狀況下直接在外在嵌套了一層函數,最外層函數接收的就是裝飾器中的參數 def home(): print("this is home page") home() @auth(auth_type="ldap") def bbs(): print("this is bbs page") bbs()