初學者python筆記(裝飾器後篇:登陸驗證)

裝飾器有非常強大的功能,可以不修改函數源代碼和調用方式,就給函數加上了對應想要的功能,簡直就是 修飾函數的利器。 上一篇文章:初學者python筆記(裝飾器、高階函數、閉包)已經非常詳細的剖析了裝飾器的原理,本篇就來實現就來具體實現一個登陸驗證的案例(源碼可以直接使用)

修飾帶參數的函數:

被修飾的函數參數個數是不固定的,而要修改參數個數就肯定需要修改裝飾器和原函數,違反了裝飾器的修改原函數源代碼的原則。
而基本裝飾器本來是不帶有參數的,如果調用原函數需要傳入參數怎麼辦?可以如下操作:

#裝飾器
import time
def timmer(func):
    def wrap(*args,**kwargs):
        #一個接收列表,一個接收字典,用容器作爲參數就可以不限參數個數了
        #相當於:foo('夏洛特玲玲','50','female','拿破崙','卡塔庫慄'),
        #args=['夏洛特玲玲','50','female','拿破崙','卡塔庫慄'],kwargs={ }
        start_time = time.time()  #給裝飾器加的功能
        res = func(*args,**kwargs)  #在裝飾器中運行函數,並且用一個變量來接收以返回原函數的返回值
        stop_time = time.time()
        print('函數運行了{}秒'.format(stop_time - start_time))
        return res  #返回原函數的返回值
    return wrap  #函數的返回值是函數,所以爲高階函數

#原函數
@timmer  #語法糖的使用,使原函數即foo函數被裝飾。相當於foo = timmer(foo)語句
def foo(name,age,sex,weapen,son):
    time.sleep(3)
    print('test函數運行完畢!\n名字:%s,年齡:%s, 性別:%s,武器:%s,兒子:%s' %(name,age,sex,weapen,son))
    return '這是test的返回值'  #爲了實現把原函數的返回值也接收到

#調用被修飾後的原函數
foo('夏洛特玲玲','50','female','拿破崙','卡塔庫慄')  #運行原函數,方式不變,滿足原則
#可以看到,加了*args和*kargs後就無論多少個參數都能正常運行了

運行結果:
test函數運行完畢!
名字:夏洛特玲玲,年齡:50, 性別:female,武器:拿破崙,兒子:卡塔庫慄
函數運行了3.0121726989746094秒

登陸驗證的實現


user_list = [   #查詢密碼的列表,包含所有的賬號密碼
    {'name':'路飛','passwd':'1111'},  #重點知識:因爲你輸入的是字符串,
    {'name':'索隆','passwd':'2222'},    #所以你字典的value也必須是字符串格式,不能是數字格式的值
    {'name':'羅','passwd':'3333'},
    {'name':'基德','passwd':'4444'}
]
current_dic = {'username':None ,'login':False}  #記錄當前用戶登陸狀態的字典

#帶驗證功能的裝飾器
def auth_func(func):
    def wrapper(*args, **kwargs):
        if current_dic['username'] and current_dic['login']:
            #如果都爲True就執行,即輸入過賬號密碼後就不需要再次輸入了
            res = func(*args, **kwargs)  #直接執行,不需要再輸入賬號密碼
            return res
        #否則就輸入賬號密碼
        username = input('用戶名:').strip()  #讓用戶輸入登陸信息
        passwd = input('密碼:').strip()
        #遍歷字典來匹配賬號密碼是否正確
        for user_dic in user_list:  #user_dic是用來遍歷列表中每個字典的變量
            #print(user_dic['name'],user_dic['passwd'])
            if user_dic['name'] == username and user_dic['passwd'] == passwd: #驗證賬號密碼 
                #print(user_dic['name'],user_dic['passwd'])
                #輸入正確就記錄下登陸狀態,用記錄狀態的字典
                current_dic['username'] = username
                current_dic['login'] = True
                #print(current_dic['login'])
                res = func(*args, **kwargs)  #接收原函數返回值
                return res
                        
        #else跟for成對,表明如果你輸入的連用戶名都不存在,那就不用遍歷了
        else:
            print('用戶名或密碼錯誤!!!')
    return wrapper  #如果密碼錯誤就不會有返回值,而是返回wrapper重新再輸入

@auth_func
def index():
    print('歡迎來到淘寶主頁!')

@auth_func
def home(name):
    print('歡迎%s回家' %name)

@auth_func
def shopping_car(name):
    print('%s的購物車裏有:%s、%s、%s' %(name,'連衣裙','海賊手辦','迪迦凹凸曼'))

print('初始用戶狀態:',current_dic)
index()
print('輸入後用戶狀態:',current_dic)
home('您')  #該函數無論傳入什麼值都可以,只是給函數內部多一個全局變量
shopping_car('您')

運行結果:
初始用戶狀態: {‘username’: None, ‘login’: False}
用戶名:索隆
密碼:2222
歡迎來到淘寶主頁!
輸入後用戶狀態: {‘username’: ‘索隆’, ‘login’: True}
歡迎您回家
您的購物車裏有:連衣裙、海賊手辦、迪迦凹凸曼

以上就是裝飾器案例的實現,如果你看了上一篇裝飾器原理的文章,本篇案例肯定是可以理解的

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章