Python3.7之裝飾器

Python3.7之裝飾器

1、裝飾器的功能

針對軟件開發的「開放-封閉」原則,即:python

封閉:已實現的功能代碼塊不該該被修改閉包

開放:對現有功能的擴展開放函數

所謂的裝飾器,就是經過裝飾器函數,來修改原函數的一些功能,使得原函數不須要修改。this

2、裝飾器引入

1.原有的功能函數以下:

def f1():
    print('f1 called: ')


def f2():
    print('f2 called: ')

2.現須要對兩個功能函數進行權限驗證,即須要引入一個閉包函數:

def w1(func):
    def inner():
        print('----權限驗證----')
        func()

    return inner

review:閉包函數的條件code

① 在一個外函數中定義了一個內函數。開發

② 內函數裏運用了外函數的臨時變量。class

③ 而且外函數的返回值是內函數的引用。test

3.裝飾後的代碼:

# 在執行w1函數的時候,此時直接把inner函數返回了,同時把它賦值給f1
# 此時的f1已經不是未加裝飾時的f1了,而是指向了w1.inner函數地址
def w1(func):
    def inner():
        print('----權限驗證----')
        func()

    return inner

# 當python解釋器執行到這句話的時候,會去調用w1函數,同時將被裝飾的函數名做爲參數傳入(此時爲f1)
@w1  # f1 = w1(f1)
def f1():
    print('f1 called: ')


@w1
def f2():
    print('f2 called: ')

# 在調用f1()的時候,其實調用的是w1.inner函數
# 那麼此時就會先執行權限驗證,而後再調用原來的f1(),該處的f1就是經過裝飾傳進來的參數f1
f1()
f2()

'''
----權限驗證----
f1 called: 
----權限驗證----
f2 called: 
'''

這樣下來,就完成了對f1的裝飾,實現了權限驗證。變量

3、對有參函數進行裝飾

若是原函數有參數,那閉包函數必須保持參數個數一致,而且將參數傳遞給原方法擴展

1.固定參數:

def w_say(fun):

    def inner(name):  # 此處應有參數
        """
        若是被裝飾的函數有形參,那麼閉包函數必須有參數
        :param name:
        :return:
        """
        print('say inner called')
        fun(name)  # 將參數傳給原方法

    return inner


@w_say
def hello(name):
    print('hello ' + name)


hello('Vivian')
'''
say inner called
hello Vivian
'''

2.非固定參數:

def w_add(func):

    def inner(*args):
        print('add inner called')
        func(*args)

    return inner


@w_add  # 共有裝飾器,被裝飾的函數的形參不固定
def add(a, b):  # 被裝飾的函數有形參
    print('%d + %d = %d' % (a, b, a + b))


@w_add
def add2(a, b, c):
    print('%d + %d + %d = %d' % (a, b, c, a + b + c))


add(2, 4)
add2(2, 4, 6)

'''
add inner called
2 + 4 = 6
add inner called
2 + 4 + 6 = 12
'''

4、對帶有返回值的函數進行裝飾

def w_test(func):
    def inner():
        print('w_test inner called start')
        # 對test進行調用以後,接收返回值s
        str0 = func()  # 原test的返回值傳遞給str0
        print('w_test inner called end')
        # 被裝飾以後的test返回值爲str0
        return str0
    return inner


@w_test  # test = w_test(test)
def test():
    print('this is test fun')
    return 'hello'


ret = test()
print('ret value is %s' % ret)

'''
w_test inner called start
this is test fun
w_test inner called end
ret value is hello
'''

5、帶參數的裝飾器

相關文章
相關標籤/搜索