3.24练习---装饰器、迭代器与生成器 1、编写带认证功能的有参装饰器 2、制作一个函数字典 3、编写日志装饰器 4、基于迭代器的方式,用while循环迭代取值字符串、列表、元组、字典、集合、文件对象 5、自定义迭代器实现range功能

3.24练习---装饰器、迭代器与生成器
1、编写带认证功能的有参装饰器
2、制作一个函数字典
3、编写日志装饰器
4、基于迭代器的方式,用while循环迭代取值字符串、列表、元组、字典、集合、文件对象
5、自定义迭代器实现range功能

可用于不同库的认证

def auth(db_type):
    def deco(func):
        def wrapper(*args,**kwargs):
            if db_type == "administrator":
                print("管理员登录。")
                name = input("请输入管理员账号:")
                password = input("请输入密码:")
                if name == "Jil" and password == "1118":
                    print("管理员登录成功!")
                    res = func(*args,**kwargs)
                    return res
                else:
                    print("账号或密码错误!")
            elif db_type == "user":
                print("用户登录。")
                name = input("请输入用户账号:")
                password = input("请输入密码:")
                with open("db.txt",mode="rt",encoding="utf-8") as f:
                    for line in f:
                        username,pwd,account = line.strip().split(":")
                        if name == username and password == pwd:
                            print(f"用户{name}登录成功!")
                            res = func(*args, **kwargs)
                            return res
                    else:
                        print("账号密码错误!")
            elif db_type == "traveler":
                print("游客登录。")
                name = input("请输入昵称:")
                print(f"欢迎游客{name}来玩!")
                res = func(*args, **kwargs)
                return res
            else:
                print("无此登录模式!")
        return wrapper
    return deco

@auth("administrator")
def administrator():
    print("您可以为所欲为!
")

@auth("user")
def user():
    print("您可进行读操作,以及部分写操作!
")

@auth("traveler")
def traveler():
    print(f"您只可进行读操作。
")

administrator()
user()
traveler()

2、制作一个函数字典

在文件开头声明一个空字典,然后在每个函数前加上装饰器,完成自动添加到字典的操作

func_dic = {}

def add_dic(func):
    for i in range(10):
        if i not in func_dic:
            func_dic[i] = func
            break
    else:
        print("函数字典已满。")
    def wrapper():
        res = func()
        return res
    return wrapper

@add_dic
def func1():
    print("来自function1")

@add_dic
def func2():
    print("来自function2")

@add_dic
def func3():
    print("来自function3")

for i in func_dic:
    func_dic[i]()

3、编写日志装饰器

实现功能如:一旦函数f1执行,则将消息2017-07-21 11:12:11 f1 run写入到日志文件中,日志文件路径可以指定

注意:时间格式的获取

import time

time.strftime('%Y-%m-%d %X')

import time
def log(file_path):
    def deco(func):
        def wrapper(*args,**kwargs):
            res = func(*args,**kwargs)
            with open(fr"{file_path}",mode="at",encoding="utf-8") as f:
                f.write(time.strftime("%Y-%m-%d %X"))
                f.write(f" {func.__name__} run
")
            return res
        return wrapper
    return deco

path = input("请指定日志存放路径:")

@log(path)
def f1(name):
    print(f"报告{name},f1已运行。")

f1("Fishball")

4、基于迭代器的方式,用while循环迭代取值字符串、列表、元组、字典、集合、文件对象

s = "abc"
s_iterator = s.__iter__()
print(s_iterator,type(s_iterator))

l = [1,2,3]
l_iterator = iter(l)
print(l_iterator,type(l_iterator))

t = (1,2,3)
t_iterator = iter(t)

d = {"1":"a","2":"b"}
d_iterator = iter(d)

se = {1,2,3}
se_iterator = se.__iter__()


while True:
    try:
        print(next(s_iterator),type(next(s_iterator)))  #  结果: a <class 'str'>
# 因为循环第一次时,  a                type(b)
# 循环第二次石,      c            抛出异常 StopIteration
# 所以无法打印,输出中断,迭代结束被捕捉。于是跳出循环

        # print(next(s_iterator))       # a  b  c
    except StopIteration:
        break

while True:
    # 字符串、列表、元组、字典、集合 均为可迭代对象,
    # 但并非迭代器对象。其中只有字符串和列表可以依靠索引遍历
    try:
        print(next(l_iterator))
    except StopIteration:
        break


with open("db.txt",mode="rt",encoding="utf-8") as f:
    # f.__iter__()          f可调用iter和next,说明f是迭代器对象。
    # f.__next__()
    while True:
        try:
            print(f.__next__(),end="")
        except StopIteration:
            break

5、自定义迭代器实现range功能

def my_range(start,end=None,step=1):

    # 满足 range(5)---》0 1 2 3 4 的情况
    if end is None:
        output = 0
        while output < start:
            yield output
            output += step
    else:

    # 满足 range(0,5,2) 设定步长输出
        if step > 0:
            while start < end:
                yield start
                start += step

    # 满足range(5,0,-1) 步长为负时,逆走
        if step < 0:
            while start > end:
                yield start
                start += step

# 测试:
for i in my_range(5,0,-2):
    print(i,end=" ")

print("")

for i in range(5,0,-2):
    print(i,end=" ")