1. 程式人生 > >python裝飾器,自己實現一個簡單的裝飾器

python裝飾器,自己實現一個簡單的裝飾器

裝飾器演變過程

1.先來看個方法:

    def add(x,y):       

        return x+y

其功能顯而易見,實現一個加法,boss覺得這個功能太單一,需要加些功能1,校驗(因為python是強型別語言,int 和string 無法直接相加.)2.相加後輸出到檔案等操作.

2.於是修改程式碼如下,這個也是改程式碼最常見的一種:

def add(x,y):
    if type(x)!=type(y):
        print("型別不一致請重試")
        return
    z=x+y
    f=open('C:\\Users\\Public\\Documents\\test.txt'
,'w') f.write(str(z)) f.close() print("finish") add(2,3)

這樣的弊端有二:1.破壞了程式高內聚低耦合原則2,加法器函式已經變了味.

3.so根據python的引用特性把加法器封裝為高階函式(引數or返回值是函式),我們這裡將add函式作為引數傳入,程式碼如下:

def add(x,y):
    return x+y

def logger(fn):
    if type(x)!=type(y):
        print("型別不一致請重試")
        return
    z=fn(x,y)
    f = open('C:\\Users\\Public\\Documents\\test.txt'
, 'w') f.write(str(z)) f.close() print("finish") x,y=4,7 logger(add)

4.函式的引數x,y沒有封裝到函式裡面,於是修改程式碼如下:

def logger(fn,x,y):
    if type(x)!=type(y):
        print("型別不一致請重試")
        return
    z=fn(x,y)
    f = open('C:\\Users\\Public\\Documents\\test.txt', 'w')
    f.write(str(z))
    f.close()
    print("finish"
) logger(add,5,8)

5.為了提高複用性,add三個引數的情況,將logge修改為可變的引數

def logger(fn,*args,**kwargs):
    if type(args[0])!=type(args[1]):
        print("型別不一致請重試")
        return
    z=fn(*args,**kwargs)
    f = open('C:\\Users\\Public\\Documents\\test.txt', 'w')
    f.write(str(z))
    f.close()
    print("finish")

logger(add,5,8)

6.柯里化後代碼如下:


def logger(fn):
    def wrapper(*args,**kwargs):
        if type(args[0]) != type(args[1]):
            print("型別不一致請重試")
            return
        z = fn(*args, **kwargs)
        f = open('C:\\Users\\Public\\Documents\\test.txt', 'w')
        f.write(str(z))
        f.close()
        print("finish")
    return wrapper

logger(add)(4,1)

7.最終我們看到了一個裝飾器,使用時候在原方法上面加@裝飾器名即可,完整程式碼如下:

 def logger(fn):
    def wrapper(*args,**kwargs):
        if type(args[0]) != type(args[1]):
            print("型別不一致請重試")
            return
        z = fn(*args, **kwargs)
        f = open('C:\\Users\\Public\\Documents\\test.txt', 'w')
        f.write(str(z))
        f.close()
        print("finish")
    return wrapper

@logger # add1 = logger(add1)
def add(x,y):
    ret = x + y
    return ret

add(12,56)