函數的開放封閉原則: 對擴展是開放的 對修改是封閉的閉包
裝飾器的主要功能:app
在不改變函數調用方式的基礎上在函數的前、後添加功能。函數
裝飾器的本質:一個閉包函數spa
裝飾器的功能:在不修改原函數及其調用方式的狀況下對原函數功能進行擴展code
裝飾器的本質是閉包函數,它與外部函數創建鏈接的參數是主函數名,也就是說,主函數名被裝飾器外層函數看成參數傳遞給了內層函數去運行.blog
裝飾器的基本結構:it
1 ===========================#裝飾器的基本形態============================= 2 def 裝飾器名 ( 被裝飾主函數名 ): 3 def 內層函數名 ( 被裝飾主函數參數 ): 4 先執行 被裝飾主函數還未執行 前 添加的操做 #裝飾器操做 5 V = 被裝飾主函數名() 6 再執行 被裝飾主函數執行結束 後 添加的動做 #裝飾器操做 7 return V #(被裝飾函數的返回值)(無關緊要) 8 return 內層函數名 #這裏是裝飾器函數的返回值,return 的是內層函數地址 9 @裝飾器名 <=====> 被裝飾主函數名 = 裝飾器名 (被裝飾主函數名) 10 # 實質上是被裝飾主函數名 = 裝飾器函數的返回值,也就是內層函數名 11 def 被裝飾函數名 ( 被裝飾函數參數 ): #這裏調用主函數,由於裝飾器而等於調用內層函數 12 被裝飾函數,也就是主體函數的函數體 13 return 主體函數的返回值 #(無關緊要) 14=========================================================================
#=====================裝飾器基本形態=========================
1 def wrapper ( func ): 2 def inner ( *args **kwargs ): 3 print('函數執行前添加的動做') 4 'V' = func( *args **kwargs ) 5 print('函數執行後添加的動做') 6 return V 7 return inner 8 @wrapper #func = wrapper ( func )--返回值-->inner 9 def func ( *args **kwargs ): 10 print('這是主函數體') 11 return V
===========================================================
在函數使用裝飾器後,查看註釋信息方法不能用,這是須要使用functool模塊的wraps功能io
1 from functools import wraps 2 3 def deco(func): 4 @wraps(func) #加在最內層函數正上方 5 def wrapper(*args,**kwargs): 6 return func(*args,**kwargs) 7 return wrapper 8 9 @deco 10 def index(): 11 '''哈哈哈哈''' 12 print('from index') 13 14 print(index.__doc__) #查看函數註釋 15 print(index.__name__) #查看函數名 16 17 裝飾器——wraps demo
for循環
class
做用:帶參數的裝飾器能夠經過最外層參數傳遞到內層來約束內層函數執行次數.條件等等
示例一 返回每次結果\列表 def outer(a): def wrapper(func): def inner(*args,**kwargs): # v=[] #添加列表 for i in range(a): z=func(*args,**kwargs) # v.append(z) #添加列表 print(z) #不添加,每次執行顯示結果 # return v return inner return wrapper @outer(5) def func(q): return q+1 print(func(1)) #注意:每次輸出返回值,最後一次返回inner的返回值none
示例二 比較返回最大值,for循環參數限制執行次數 def outer(a): def wrapper(func): def inner(*args,**kwargs): v=0 for i in range(a): z=func(*args,**kwargs) if z>v: v=z print(z) return z return inner return wrapper @outer(5) def func(i): return 8 print(func(1))
示例三 分狀況決定是否執行裝飾函數 True False def outer(a): def wrapper(func): def inner(*args,**kwargs): if a: z=func(*args,**kwargs) return z else: z = func2(*args, **kwargs) return z return inner return wrapper @outer(True) def func(i): print('第一種狀況下執行') print(func(1)) @outer(False) def func2(i): print('第二種狀況下') print(func(2))