裝飾器

函數的開放封閉原則:  對擴展是開放的 對修改是封閉的閉包

裝飾器的主要功能: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循環

  1.執行外部裝飾器函數wrapper,並把被裝飾函數func看成參數傳遞給裝飾器wrapper(func)class

   2.把裝飾器函數的返回值賦值給被裝飾函數 func = wrapper (func)返回值=inner#內部函數

裝飾器的用法: 在被裝飾函數的上面加語法糖@裝飾器名,再上面建立 裝飾器名(被裝飾函數) 函數,再創建 內層函

數(攜帶被裝飾函數參數) ,在內層函數函數體中執行被裝飾函數先後加新功能,正常輸出,給外層裝飾器返回值爲內層函數.

帶參數的裝飾器

  • 做用:帶參數的裝飾器能夠經過最外層參數傳遞到內層來約束內層函數執行次數.條件等等

示例一    返回每次結果\列表
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))
相關文章
相關標籤/搜索