• 3.23练习---装饰器练习


    一、带时间统计功能与认证功能的装饰器

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

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

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

    import time
    def timmer(func):
        # func = py
        def wrapper(*args,**kwargs):
            start = time.time()         # 时间戳。从Unix系统第一次运行的1970年(unix元年)到现在这个时刻的秒数
            res = func(*args,**kwargs)
            end = time.time()
            print("运行时间为",end-start)
            return res
        return wrapper
    
    def auth(func):
        def wrapper(*args,**kwargs):
            username = input("请输入用户名:")
            pwd = input("请输入密码:")
            if username == "fishball" and pwd == "188741":
                print("登陆成功!正在启动程序!")
                res = func(*args,**kwargs)
                return res
            else:
                print("密码或账号错误,登陆失败!")
        return wrapper
    
    @auth       # step2: py = auth(timmer.<local>.wrapper)
    @timmer     # step1: timmer.<local>.wrapper的内存地址 = timmer(py)
    def py(name):
        time.sleep(3)
        print(f"欢迎{name}进行py!")
    
    py("fishball")

    二、认证功能装饰器(带登录超时验证)

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

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

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

    import time
    import os
    def permission(func):
        def wrapper(*args,**kwargs):
    
            # 若 logined.txt存在,则需要打开logined.txt,取出里面保存的时间戳
            # 不存在,则直接进入登录功能
            if os.path.exists(r"logined.txt"):
                with open("logined.txt",mode="rt",encoding="utf-8") as f:
                    login_time = f.read()
                    login_time = float(login_time)
                    now = time.time()
    
                    # 对比当时保存的时间戳与现在的时间差,若超出60秒,则超时,需要重新登录
                    if now - login_time <= 60:
                        res = func(*args, **kwargs)
                        return res
                    else:
                        print("登录超时!")
            while True:
                username = input("请输入用户名(q:quit):")
                if username == "Q" or username == "q":
                    break
                with open("db.txt",mode="rt",encoding="utf-8") as f:
                    for line in f:
                        name,pwd,account = line.strip().split(":")
                        if name == username:
                            while True:
                                password = input("请输入密码(q:rename):")
                                if password == "q" or password == "Q":
                                    break
                                if password == pwd:
                                    print("登陆成功!")
    
                                    # 登录成功,则写入当前时间
                                    with open("logined.txt",mode="wt",encoding="utf-8") as f1:
                                        f1.write(f"{time.time()}")
                                    res = func(*args, **kwargs)
                                    return res
                                else:
                                    print("密码错误!请重新输入")
                            break
                    else:
                        print("账号不存在,请重新输入")
        return wrapper
    
    @permission
    def py(name):
        time.sleep(3)
        print(f"欢迎{name}进行py!")
    
    @permission
    def ky(name):
        time.sleep(3)
        print(f"欢迎{name}进行py!")
    
    func_dic = {"1":("py函数",py),"2":("ky函数",ky),"0":("退出",exit)}
    
    while True:
        print(" Function Store ".center(50,"-"))
    
        # 根据字典打印用户交互界面
        for key in func_dic:
            print(key,func_dic[key][0])
        print(" The End ".center(50,"-"))
    
        cmd = input("请输入需要执行的函数代号:")
        # 判断输入指令是否为数字
        if cmd.isdigit():
            if cmd in func_dic:
    
                # 若cmd为0,退出程序,则账户登录应一同退出,故删去logined.txt
                if cmd == "0":
                    os.remove("logined.txt")
                func_dic[cmd][1](1)
            else:
                print(f"代号{cmd}不存在")
        else:
            print("请输入数字!")
        input("按Enter键继续。")
  • 相关阅读:
    BZOJ 1036 树的统计
    codevs 4712 gcd与lcm问题
    codevs 1574 矩阵乘法
    Python定时任务框架APScheduler
    PHP集成支付宝快速实现充值功能
    玩转Web之easyui(二)-----easy ui 异步加载生成树节点(Tree),点击树生成tab(选项卡)
    玩转Web之easyui(一)-----easy ui datagird 分页
    Android访问服务器(TOMCAT)乱码引发的问题
    工厂方法模式--结合具体例子学习工厂方法模式
    简单工厂模式--结合实例学习简单工厂模式
  • 原文地址:https://www.cnblogs.com/zhubincheng/p/12555480.html
Copyright © 2020-2023  润新知