Python中裝飾器語法初識,以及用到的高階函數、閉包

'''
裝飾器,閉包,高階函數同時使用

'''

account = {
    'is_authenticated': False,    # 打開網站時默認用戶未登錄,用戶登錄成功則改成True
    'username':'alex',
    'password':'abc123'
}


# 定義一個登錄函數
def login(func):   # func表示把一個函數當成參數再傳給另一個函數


    def inner(*args,**kwargs):   # 在定義一層函數實現閉包,
        if account['is_authenticated'] is False:   # 判斷用戶沒有登錄,需要用戶輸入登錄信息
            username = input('請輸入您的賬戶:')
            password = input('請輸入您的密碼:')
            if username == account['username'] and password == account['password']:
                print('登錄成功')
                account['is_authenticated'] = True
                func(*args,**kwargs)      # 認證成功,執行功能函數   func()就相當於執行功能america()函數
            else:
                print('用戶名或者密碼錯誤')
        else:
            print('用戶已經登錄,驗證通過')
            func(*args,**kwargs)  # 認證成功,執行功能函數

    return inner     # 返回值是inner的內存地址,不執行函數


def home():
    print('----首頁-----')

@login   # 裝飾器語法
def america():
    # login()     # 執行前加上登錄驗證
    print('------歐美專區----------')


def japan():
    print('--------日本專區-----------')

@login    # 裝飾器語法
def chinese(vip_level):
    # login()     # 執行前加上登錄驗證

    # 最後想再加一個功能,判斷用戶VIP等級
    if vip_level > 5:
        print('解鎖本專區所有資源')
    else:
        print('中文專區普通資源')


home()
'''
如何在不違背軟件開發中的“開發---封閉”基礎上:實現在指定網站頁面驗證用戶是否登錄
    我只需要寫個認證方法,每次調用需要驗證的功能時,直接把這個功能的函數名當做一個參數傳給我的驗證模塊即:使用高階函數方法
'''
# login(america)   # 網站某某區的功能,需要驗證用戶登錄與否,就直接調用login,把需要驗證的功能當成一個參數傳給login即可
# login(chinese)   # 改變了調用方式違背了開發---封閉原則

# america = login(america)   # 上面用到的@login 就不需要這兩行代碼了
# chinese = login(chinese)
'''
運行結果:下面兩句代碼會報錯TypeError: 'NoneType' object is not callable 
    表示下面兩個函數調用報錯,因爲他們兩個此時是一個None.爲什麼、會是None了?
    因爲當代碼執行到america = login(america) ,就會執行函數america(),而執行這個功能時,我們沒有返回任何值,如果再執行america(),就會報錯
    要想避免這種問題:就需要用到閉包了
'''
america()  # 有了上面兩句代碼,我再寫這兩句代碼,源代碼的調用方式我就沒有改變了
chinese(7)   # 有了上面的閉包現象,這行代碼相當於執行inner()函數
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章