作业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('
').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
" % (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(' ').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 " % (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(' ').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("{} {}{}{}元 ".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(' ').split(':') if add_money > 0: old_data[2] = str(int(old_data[2]) + add_money) new_line = ':'.join(old_data) + ' ' 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(' ').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) + ' ' 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
原文地址:https://www.cnblogs.com/cui-cheng/p/13179825.html