day17

一:编写函数,(函数执行的时间用time.sleep(n)模拟)

import time

def run(x):
    time.sleep(2)
    print(f'{x}正在打印。。。')
    return '函数run执行完毕'

二:编写装饰器,为函数加上统计时间的功能

def timer(func):
    def wrapper(*args, **kwargs):
        start = time.time()
        res = func(*args, **kwargs)
        stop = time.time()
        print(stop - start)
        return res
    return wrapper
 
@timer #run = timer(run)
def run(x):
    time.sleep(2)
    print(f'{x}正在打印。。。')
    return '函数run执行完毕'

res = run('hello world')
print(res)

三:编写装饰器,为函数加上认证的功能

def login_auth(func):
    def wrapper(*args, **kwargs):
        name = input('请输入用户名:').strip()
        password = input('请输入密码:').strip()
        if name == 'han' and password == '123':
            res = func(*args, **kwargs)
            return res
        else:
            print('用户名或密码错误!')
    return wrapper

四:编写装饰器,为多个函数加上认证的功能(用户的账号密码来源于文件),要求登录成功一次,后续的函数都无需再输入用户名和密码

注意:从文件中读出字符串形式的字典,可以用eval('{"name":"egon","password":"123"}')转成字典格式

'''{'username':'han', 'password':'123'}'''
userInfo = {'username': None}

def login():
    user_name = input('请输入用户名:').strip()
    user_pwd = input('请输入密码:').strip()
    with open('user_info.txt', 'rt', encoding='utf-8')as f:
        for line in f:
            user_info = eval(line.strip())
            if user_name == user_info['username'] and user_pwd == user_info['password']:
                userInfo['username'] = user_name
                print('登录成功!')
            else:
                print('用户名或密码错误!')

def login_auth(func):
    def wrapper(*args, **kwargs):
        if userInfo['username']:
            res = func(*args, **kwargs)
            return res
        else:
            print('用户未登录,请先登录!')
            login()
    return wrapper


@login_auth
def check_balance():
    print('check_balance正在执行。。。')


@login_auth
def withdraw():
    print('withdraw正在执行。。。')


@login_auth
def transfer():
    print('transfer正在执行。。。。')

func_dic = {
    '1':('登录',login),
    '2':('查看余额',check_balance),
    '3':('提现',withdraw),
    '4':('转账',transfer)
}

def run():
    while True:
        for line in func_dic:
            print(line, func_dic[line][0])
        choice = input('请输入功能编号:').strip()
        if choice == 'q':
            break
        if choice in func_dic:
            func_dic.get(choice)[1]()

if __name__ == '__main__':
    run()

五:编写装饰器,为多个函数加上认证功能,要求登录成功一次,在超时时间内无需重复登录,超过了超时时间,则必须重新登录

userInfo = {'username': None,
            'start':None}

def login():
    user_name = input('请输入用户名:').strip()
    user_pwd = input('请输入密码:').strip()
    with open('user_info.txt', 'rt', encoding='utf-8')as f:
        for line in f:
            user_info = eval(line.strip())
            if user_name == user_info['username'] and user_pwd == user_info['password']:
                userInfo['username'] = user_name
                userInfo['start'] = time.time()
                print('登录成功!')
            else:
                print('用户名或密码错误!')


#认证装饰器
def login_auth(func):
    def wrapper(*args, **kwargs):
        if userInfo['username']:
            res = func(*args, **kwargs)
            return res
        else:
            print('用户未登录,请先登录!')
            login()
    return wrapper

import time
#时间装饰器
def timer(func):
    def wrapper(*args, **kwargs):
        if userInfo['username']:
            stop = time.time()
            # print('stop:', stop)
            start = int(userInfo['start'])
            # print(stop - start)
            if stop-start < 6:
                res = func(*args, **kwargs)
                return res
            else:
                userInfo['username'] = None
                userInfo['start'] = None
                print('登录超时,请重新登录')
    return wrapper


@login_auth
@timer
def check_balance():
    print('check_balance正在执行。。。')


@login_auth
@timer
def withdraw():
    print('withdraw正在执行。。。')


@login_auth
@timer
def transfer():
    print('transfer正在执行。。。。')

func_dic = {
    '1':('登录',login),
    '2':('查看余额',check_balance),
    '3':('提现',withdraw),
    '4':('转账',transfer)
}

def run():
    while True:
        for line in func_dic:
            print(line, func_dic[line][0])
        choice = input('请输入功能编号:').strip()
        if choice == 'q':
            break
        if choice in func_dic:
            func_dic.get(choice)[1]()

if __name__ == '__main__':
    run()

六:选做题

思考题(选做),叠加多个装饰器,加载顺序与运行顺序,可以将上述实现的装饰器叠加起来自己验证一下

@deco1 # index=deco1(deco2.wrapper的内存地址)
@deco2 # deco2.wrapper的内存地址=deco2(deco3.wrapper的内存地址)
@deco3 # deco3.wrapper的内存地址=deco3(index)
def index():
		pass
加载顺序:deco3 deco2 deco1
运行顺序:deco1 deco2 deco3
posted @ 2020-03-23 18:13  蛋蛋的丶夜  阅读(56)  评论(0编辑  收藏  举报