作业day16
2020-06-22
1、编写课上讲解的有参装饰器
def auth(mode): def outer(func): def wrapper(*args, **kwargs): while True: inp_name = input("请输入您的用户名:") inp_pwd = input("请输入您的密码:") if mode == 'file': print('approve from file') with open('info.db', mode='r', encoding='utf-8') as f: for line in f: name_db, pwd_db = line.strip('\n').split(':') if inp_name == name_db and inp_pwd == pwd_db: print('login success') res = func(*args, **kwargs) return res else: print('login error') elif mode == 'mysql': print("approve from mysql") res = func(*args, **kwargs) return res elif mode == "ldap": print('approve from ldap') res = func(*args, **kwargs) return res else: print('mode error') return wrapper return outer @auth('mysql') def index(x, y): print(x, y) return 123 res = index(1, 2) print(res)
2. 还记得我们用函数对象的概念,制作一个函数字典取代多分支if的操作吗,来来来,我们有更高大上的做法,
在文件开头声明一个空字典,然后在每个函数前加上装饰器,完成自动添加到字典的操作
dic = {} def outer(func): def wrapper(*args, **kwargs): res = func(*args, **kwargs) l1 = [] for v in dic.values(): l1.append(v) if func not in l1: dic[str(len(dic) + 1)] = res return res return wrapper @outer def login(): print('登录功能') return '登录', login login() @outer def register(): print('注册功能') return '注册', register register() @outer def transfer(): print('转账功能') return '转账', transfer transfer() @outer def charge(): print('充值') return '充值', charge charge() @outer def withdraw(): print('提现') return '提现', withdraw withdraw() print(dic)
3、 编写日志装饰器,实现功能如:一旦函数f1执行,则将消息2017-07-21 11:12:11 f1 run写入到日志文件中,日志文件路径可以指定=》有参装饰器
注意:时间格式的获取
import time
time.strftime('%Y-%m-%d %X')
import time def outer2(mode): def outer(func): def wrapper(*args, **kwargs): if mode == 'file': with open('access.log', mode='at', encoding='utf-8')as f: f.write("%s %s run\n" % (time.strftime('%Y-%m-%d %X'), func.__name__)) res = func(*args, **kwargs) return res return wrapper return outer @outer2('file') def index(x): print(x) index(10)
4、基于迭代器的方式,用while循环迭代取值字符串、列表、元组、字典、集合、文件对象
字符串:
msg = 'hello' msg_iter = iter(msg) while True: try: item = next(msg_iter) print(item) except StopIteration: break
列表:
l1 = [1,2,3,4] l1_iter = iter(l1) while True: try: item = next(l1_iter) print(item) except StopIteration: break
元组:
t1 = (1, 2, 3, 4, 5) t1_iter = iter(t1) while True: try: item = next(t1_iter) print(item) except StopIteration: break
字典:
dic = {'k1': 'aaa', 'k2': 'bbb', 'k3': 'ccc'} dic_iter = iter(dic) while True: try: k = next(dic_iter) print(k, dic[k]) except StopIteration: break
集合:
set = {111, 222, 333, 444} set_iter = iter(set) while True: try: item = next(set_iter) print(item) except StopIteration: break
文件对象:
with open('info.db', 'r', encoding='utf-8') as f: f_iter = iter(f) while True: try: line = next(f_iter) print(line, end="") except StopIteration: break
选做作业:
编写小说阅读程序实现下属功能
一:程序运行开始时显示
0 账号注册
1 充值功能
2 阅读小说
二: 针对文件db.txt,内容格式为:"用户名:密码:金额",完成下述功能
2.1、账号注册
2.2、充值功能
三:文件story_class.txt存放类别与小说文件路径,如下,读出来后可用eval反解出字典
{"0":{"0":["倚天屠狗记.txt",3],"1":["沙雕英雄转.txt",10]},"1":{"0":["令人羞耻的爱.txt",6],"1":["二狗的妻子与大草原的故事.txt",5]},}
3.1、用户登录成功后显示如下内容,根据用户选择,显示对应品类的小说编号、小说名字、以及小说的价格
"""
0 玄幻武侠
1 都市爱情
2 高效养猪36技
"""
3.2、用户输入具体的小说编号,提示是否付费,用户输入y确定后,扣费并显示小说内容,如果余额不足则提示余额不足
四:为功能2.2、3.1、3.2编写认证功能装饰器,要求必须登录后才能执行操作
五:为功能2.2、3.2编写记录日志的装饰器,日志格式为:"时间 用户名 操作(充值or消费) 金额"
import os import time from functools import wraps login_user = None change_money = 0 func1 = None
print('0 账号注册', '1 充值功能', '2 阅读小说') def register(): # 注册 tag = True while tag: inp_name = input("请注册您的用户名:").strip() with open('db.txt', mode='r+t', encoding='utf-8') as f: l = [] for line in f: name, *_ = line.strip('\n').split(":") l.append(name) if inp_name not in l: while True: inp_pwd = input("请注册您的数字密码:").strip() if inp_pwd.isdigit(): re_pwd = input("请确认您的数字密码:").strip() if inp_pwd == re_pwd: f.seek(0, 2) f.write("%s:%s:0\n" % (inp_name, inp_pwd)) tag = False break else: print("两次输入不一致,请重新输入") else: print("格式有误,请重新注册密码") else: print('您输入的用户名已存在') def outer(func): # 登录认证装饰器 @wraps(func) def wrapper1(*args, **kwargs): tag = True while tag: inp_name = input('请输入您的用户名:') inp_pwd = input('请输入您的密码:') with open('db.txt', mode='r', encoding='utf-8') as f: for line in f: user_name, pwd, money = line.strip('\n').split(":") if inp_name == user_name and inp_pwd == pwd: print("登录成功!") global login_user login_user = inp_name tag = False res = func(*args, **kwargs) return res return wrapper1 def monitor(func): # 日志装饰器 @wraps(func) def wrapper2(*args, **kwargs): start_time = time.strftime('%Y-%m-%d %H-%M-%S') res = func(*args, **kwargs) with open('access.log', mode='a', encoding='utf-8') as f: f.write("{} {}{}{}元\n".format(start_time, login_user, '充值了' if func1 == charge else '消费了', change_money)) return res return wrapper2 @outer @monitor def charge(user, add_money): # 充值 with open('db.txt', mode='r', encoding='utf-8') as f: for line in f: if user in line: old_line = line old_data = line.strip('\n').split(':') if add_money > 0: old_data[2] = str(int(old_data[2]) + add_money) new_line = ':'.join(old_data) + '\n' f.seek(0, 0) res = f.read().replace(old_line, new_line) global change_money change_money = add_money global func1 func1 = charge else: print('金额不得小于0') return with open('new_db.txt', mode='w', encoding='utf-8') as p: p.write(res) os.remove('db.txt') os.renames('new_db.txt', 'db.txt') @outer @monitor def reading(): # 购买小说 with open('story_class.txt', mode='r', encoding='utf-8') as f: dic = eval(f.read()) print("""0 玄幻武侠 1 都市爱情 2 高效养猪36技""") while True: cmd = input('请输入您想看的类别编号:').strip() if cmd not in ['0', '1', '2']: print('您输入的编号不存在,请重新输入') else: for k, v in dic[cmd].items(): print('%s %s price: %s' % (k, v[0], v[1])) # 目录价格 tag = True while tag: # 购买 num = input("请选择需要购买的书籍:").strip() if num in dic[cmd]: inp_cmd = input('请确认购买(确认输入"y",否则输入"n"):').strip() if inp_cmd == 'y': # 确认购买 with open('db.txt', mode='r', encoding='utf-8') as f, \ open(r'new_db.txt', mode='w', encoding='utf-8') as p: for line in f: if login_user in line: old_line = line old_info = line.strip('\n').split(':') money = int(old_info[-1]) if money < dic[cmd][num][-1]: print('当前余额不足') return else: money -= dic[cmd][num][-1] global change_money change_money = dic[cmd][num][-1] global func1 func1 = reading old_info[-1] = str(money) new_line = ':'.join(old_info) + '\n' f.seek(0, 0) res = f.read().replace(old_line, new_line) p.write(res) tag = False os.remove('db.txt') os.renames('new_db.txt', 'db.txt') with open(dic[cmd][num][0], mode='r', encoding='utf-8') as f1: # 显示小说内容 data = f1.read() print(data) return else: return