python學習筆記——裝飾器

裝飾器函數——用來對函數的擴展,補充。

高階函數+嵌套函數 =》裝飾器


原則:

1 / 不能修改被裝飾的函數的源代碼

2 / 不能修改被裝飾的函數的調用方式

實現裝飾器的知識儲備:

1 / 函數即‘變量’

def test():

      函數體

-----------------

test = '函數體'

2 / 高階函數

兩個條件:

1 / 把一個函數名當作實參傳給另外一個函數(在不修改被裝飾函數源代碼的情況下爲其添加功能)

2 / 返回值中包含函數名(不修改函數的調用方式)

import time

def bar():
    time.sleep(2)
    print('in the bar')

def test2(func):
    print(func)
    return(func)
#
# print(test2(bar))
bar = test2(bar)
bar()

3 / 嵌套函數

裝飾器的代碼示例:

高階函數+嵌套函數 =》裝飾器

1 / 不能修改被裝飾的函數的源代碼

2 / 不能修改被裝飾的函數的調用方式

由簡到繁的代碼說明裝飾器:

——沒有傳遞參數的代碼示例講解:

import time
def timer(func):##裝飾器
    def deco():
        start_time = time.time()
        func()
        end_time = time.time()
        print('the fun run time is %d' %(end_time-start_time))
    return deco

@timer ##語法糖 等價於test1 = timer(test1)
def test1():
    time.sleep(2)
    print('in the test1')

test1()
'''
註解:
當test()調用時,實際因爲語法糖的功能,等價於test1 = timer(test1),於是調用了裝飾器timer,
timer傳入test1函數作爲參數,運行裝飾器下面的deco函數,執行deco函數,並return deco,注意這個deco沒有小括號,返回的是deco的內存地址值。
最後調用test1()實際上是 “deco內存地址值()”在運行。
'''

——被裝飾函數需要傳遞參數的代碼實力講解:

import time
def timer(func):##裝飾器
    def deco(*args,**kwargs):##test2調用的時候傳遞了參數name,調用裝飾器的時候,deco()也需要有參數name
        ##由於傳遞進來的參數不好確定,所以用*args,**kwargs接收
        start_time = time.time()
        func(*args,**kwargs)
        end_time = time.time()
        print('the fun run time is %d' %(end_time-start_time))
    return deco

@timer ##語法糖 等價於test1 = timer(test1)
def test1():
    time.sleep(2)
    print('in the test1')
@timer ##語法糖 等價於test2 = timer(test2)
def test2(name):  ##test2調用的時候傳遞了參數name,調用裝飾器的時候,deco()也需要有參數name
    time.sleep(3)
    print('name:',name)

test1()
test2('drglon')
'''
註解:
當test2()調用時傳入了參數name,實際因爲語法糖的功能,等價於test2 = timer(test2(name)),於是調用了裝飾器timer,並傳入參數
timer傳入test2(name)函數作爲參數,運行裝飾器下面的deco函數,並把參數name傳遞給deco函數,
執行deco(name)函數,並return deco,注意這個deco沒有小括號,返回的是deco的內存地址值。
最後調用test2(name)實際上是 “deco內存地址值(name)”在運行。
因爲裝飾器中deco()函數需要接收的參數不固定,所以用*args,**kwargs接收。變的通用。
'''
——關於被裝飾函數的返回值如何體現

import time

user,passwd = 'dralon','abc123'
def auth(func):
    def wrapper(*args,**kwargs):##調用的時候有可能傳遞了參數,調用裝飾器的時候,裝飾器的函數也需要有參數
        username = input('Username:').strip()
        password = input('Passwd:').strip()

        if user ==username and passwd == password:
            print('has authentication')
            res = func(*args,**kwargs)  ##實際上home()的時候,home()的return home返回值需要在這裏體現。設置一個變量儲存home()函數的return home 返回值
            print("這個是個home()的返回值 %s" %res)
        else:
            print('please input ')
    return wrapper

def index():
    print('welcom to index page')

@auth
def home():
    print('welcom to home page')
    return home   ##這個返回結果,在裝飾器中要有返回才能體現出來

@auth
def bbs():
    print('welcom to bbs page')

# index()
home()
# bbs()






高階函數+嵌套函數 =》裝飾器
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章