python -- 裝飾器

一、關於函數的裝飾器
 
開閉原則:
    對功能的擴展
    對代碼的修改是封閉
 
通用裝飾器語法(python裏面的動態代理)
存在的意義:在不破壞原有函數和原有函數調用的基礎上,給函數添加新的功能
def wrapper(fn):    # fn是目標函數
    def inner(*args, **kwargs):  # 聚合   爲目標函數傳參,無敵傳參,接收到的是元組
        # 在執行目標函數以前
        ret = fn(*args, **kwargs) # 接收到的全部參數,打散傳遞給正常參數, 調用目標函數,ret是目標函數的返回值
        # 在執行目標函數以後
        return ret  # 把目標函數返回值返回,保證函數正常運行
    return inner

@wrapper  # target_func = wrapper(target_func)  # 此時fn就是target_func
def target_func():
    pass

target_func()  # 此時執行的是inner()

二、帶有參數的裝飾器 python

def wrapper_out(flag): # 裝飾器自己的參數
    def wrapper(fn): # 目標函數
        def inner(*args, **kwargs): # 目標函數執行須要的參數
            if flag == True:
                print('看看天氣預報,知道明每天氣怎麼樣')
                ret = fn(*args,**kwargs) # 在執行目標函數以前
                print('下雨了,天氣預報不太準啊')
                return ret
            else:
                ret = fn(*args,**kwargs) # 在執行目標函數以前
                return ret
        return inner
    return wrapper

#語法糖 @裝飾器
@wrapper_out(True) # 先執行wrapper_out(True),返回一個裝飾器,再和@拼接 @裝飾器
def pashan(): #被wrapper裝飾
    print('去登山了')

pashan()

三、多個裝飾器裝飾同一個函數 app

def wrapper1(fn):
    def inner(*args,**kwargs):
        print(1111)
        ret = fn(*args, **kwargs)
        print(2222)
        return ret
    return inner

def wrapper2(fn):
    def inner(*args, **kwargs):
        print(3333)
        ret = fn(*args, *kwargs)
        print(4444)
        return ret
    return inner


# 就近原則
@wrapper1
@wrapper2

def func():
    print('今天你在作什麼')

func()

'''
1111
3333
今天你在作什麼
4444
2222
'''

執行順序:首先@wrapper1裝飾起來,而後獲取到一個新函數是wrapper1中的inner,而後執行@wrapper2,這個時候,@wrapper2裝飾的就是@wrapper1中的inner了,因此執行順序就像:第二層裝飾器前(第一層裝飾器前(目標)第一層裝飾器後)第二層裝飾器後,程序從左到右執行起來 函數

相關文章
相關標籤/搜索