1. 程式人生 > >Python入門學習筆記03(裝飾器)

Python入門學習筆記03(裝飾器)

語法糖 替換 開頭 ogg highlight 使用 情況 war \n

裝飾器

裝飾器的本質就是一個函數,它的作用是在不改變被裝飾函數代碼及調用方式的情況下為被裝飾函數加上一些功能,
可以說裝飾器對於被裝飾函數來說是完全透明的。

裝飾器的實現方式利用了高階函數和嵌套函數,建立裝飾器的流程如下:
1.定義一個高階函數,擁有一個函數參數
2.在高階函數中定義一個內部函數,調用傳入的函數參數完成被裝飾函數的功能,其他代碼實現要增加的功能
3.將內部函數作為高階函數的返回值
4.在被修飾函數定義的時候使用語法糖@將被修飾函數的調用替換為高階函數返回的內部函數,
從而實現在沒有改變被裝飾函數代碼及調用方式的情況下添加新功能。

import time
#裝飾器函數,作用為模擬在被裝飾函數的開頭和結尾添加日誌
def Logger(Func):
    def deco(*args,**kvargs):#可變長度參數,應對不同被裝飾函數的不同參數,直接傳入內部Func的
        print("\nLog in start...")
        Func(*args,**kvargs)
        print("Log in end...")

    return deco

#為裝飾器函數添加非函數類型的參數,實際上就是在原來的裝飾函數上再套上了一個函數,最外層的函數用於傳入參數
def Logger2(params = ""):
    def outer_deco(Func):
        def deco(*args,**kwargs):
            if  params == "Type1":
                print("\n按照Type1形式記錄日誌")
            elif params == "Type2":
                print("\n按照Type2方式記錄日誌")
            Func(*args,**kwargs)
            print("Log in end...")
        return deco
    return outer_deco

#不使用裝飾器,無影響
def Func_Test1():
    print("\nTest1 start")
    time.sleep(1)
    print("Test1 stop")

#使用裝飾器,在運行前後打上日誌
@Logger
def Func_Test2():
    print("\nTest2 start")
    time.sleep(1)
    print("Test2 stop")

#使用裝飾器,在運行的前後打上日誌
@Logger # 這個語法糖相當於Func_Test3 = Logger,亦即Func_Test3 = deco
def Func_Test3(msg):
    print("\nTest3 start")
    print(msg)
    time.sleep(1)
    print("Test3 stop")

#帶上參數的裝飾函數,此時變成了Func_Test4 = Logger2()
@Logger2()
def Func_Test4():
    print("\nTest4 start")
    time.sleep(1)
    print("Test4 stop")

@Logger2(params ="Type2")
def Func_Test5(msg = ""):
    print("\nTest5 start")
    print(msg)
    time.sleep(1)
    print("Test5 stop")

  調用

Func_Test1()
Func_Test2()
Func_Test3("傳入參數")

  輸出

Test1 start
Test1 stop

Log in start...

Test2 start
Test2 stop
Log in end...

Log in start...

Test3 start
傳入參數
Test3 stop
Log in end...

  調用

Func_Test4()
Func_Test5("傳入參數")

  輸出

Test4 start
Test4 stop
Log in end...

按照Type2方式記錄日誌

Test5 start
傳入參數
Test5 stop
Log in end...

  

Python入門學習筆記03(裝飾器)