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键继续。")
原文地址:https://www.cnblogs.com/zhubincheng/p/12555480.html