zoukankan      html  css  js  c++  java
  • python基础学习-day17==课后作业练习(无参装饰器)

    # 必做题:
    # 1.编写函数,(函数执行的时间用time.sleep(n)模拟)
    import time
    
    def func(x, y):
        num = x + y
        time.sleep(3)
        print(num)
        return num
    # 2.编写装饰器,为函数加上统计时间的功能
    import time  # 源码
    
    
    # 统计时间装饰器
    def timer(func):  # func ---> 被装饰对象
        def inner(*args, **kwargs):  # 被装饰对象需要接收的参数
    
            # 被装饰对象执行之前的时间
            start_time = time.time()
            # *args, **kwargs将接收过来的参数,传给调用的被装饰对象,会得到一个返回值
            res = func(*args, **kwargs)  # 调用被装饰对象, 这行代码就是被装饰对象的执行全过程
            # 被装饰对象执行结束后的时间
            end_time = time.time()
    
            # 打印被装饰对象的执行时间
            # func.__name__ ---> 可以获取函数的名称
            print(f'当前被装饰对象[{func.__name__}] 执行时间为: [{end_time - start_time}]')
            return res
    
        return inner
    
    
    @timer  # timer = inner = timer(func)
    def func_demo():
        time.sleep(3)  # 单位: 秒
    # 使用装饰器的目的: 1装饰对象添加新的功能 2、前提: 不修改被装饰对象的源代, 不修改用方式
    # inner = timer(func)
    # func = inner
    # func() # --> inner()
    # func_demo()
    
    
    import os
    
    def timer(func):
        def wrapper(*args, **kwargs):
            start = time.time()
            res = func(*args, **kwargs)
            end = time.time()
            print(end - start)
            return res
    
        return wrapper
    
    num = timer(num)
    num(1,2)
    # 3.编写装饰器,为函数加上认证的功能
    # 全局变量: 用于记录是否有用户登录
    login_user = None
    
    
    # 登录功能
    def login():
        username = input('请输入用户名: ').strip()
        password = input('请输入密码: ').strip()
        if username == 'tank' and password == '123':
            print('登录成功')
            # 登录成功后,给全局变量赋值,记录当前用户已经登录
            global login_user
            login_user = username
    
        else:
            print('登录失败')
    
    
    # 登录认证装饰器
    def login_auth(func):
        def inner(*args, **kwargs):
            # 被装饰对象执行前,为其添加新的功能
            # 在此处做登录认证
            if login_user:
                # 被装饰对象执行  func ---> play, shopping
                res = func(*args, **kwargs)
                return res
    
                # 被装饰对象执行后,为其添加新的功能
            else:
                print('未有用户登录,无法使用好玩的功能!')
                login()
    
        return inner
    
    # play 与 shopping 功能使用前 必须先登录 否则,不允许使用,让其执行登录功能
    @login_auth
    def play():
        # 不使用装饰器
        # if not login_user:
        #     login()
        print('开始play了啊....')
        pass
    
    
    @login_auth
    def shopping():
        pass
    # login()
    # play()
    # shopping()
    import os
    
    def login(func):
        def wrapper(*args,**kwargs):
            user_name = input('请输入用户名:')
            user_psd = input('请输入密码:')
            with open('name.txt','rt',encoding='utf-8')as f:
                for line in f:
                    username,password = line.strip().split(':')
                if username==user_name and user_psd==password:
                    print('登陆成功!')
                #   执行之前的num函数
                    res = func(*args,**kwargs)
                    return res
                else:
                    print('登录失败!')
        return wrapper
    num
    =login(num) num(1,2)
    # 4.编写装饰器,为多个函数加上认证的功能(用户的账号密码来源于文件),要求登录成功一次,后续的函数都无需再输入用户名和密码
    # 注意:从文件中读出字符串形式的字典,可以用eval('{"name":"egon","password":"123"}')转成字典格式
    # 1、打开db.txt文件,读取用户数据,转成字典类型
    with open('db.txt', 'r', encoding='utf-8') as f:
        # 直接读取文件中的数据,得到的数据类型是: str
        user_data = f.read()
        print(user_data, type(user_data))
        '''
        {"name": "tank", "pwd": "123"}
        '''
        # eval(str) ---> 从str字符串中,检测python代码的语法,
        # 如果里面有{key: value},会将该数据生成对应的类型的内存地址
        user_dic = eval(user_data)
        print(user_dic, type(user_dic))
    
    user_dic = user_dic
    # print(user_dic)
    # print(type(user_dic))
    login_info = None
    
    def login():
        username = input('请输入用户名: ').strip()
        if username in user_dic.get('name'):
            password = input('请输入密码: ').strip()
            if password == user_dic.get('pwd'):
                print('login successful')
                global login_info
                login_info = {username: password}
    
            else:
                print('密码错误')
        else:
            print('用户不存在')
    
    
    def login_auth(func):
        def inner(*args, **kwargs):
            if login_info:
                res = func(*args, **kwargs)
                return res
            else:
                login()
        return inner
    
    
    @login_auth
    def withdraw():
        pass
    @login_auth
    def shopping():
        pass

    # 5.编写装饰器,为多个函数加上认证功能,要求登录成功一次,在超时时间内无需重复登录,超过了超时时间,则必须重新登录
    import time
    
    # 全局变量,用于计算函数登录后的执行总时长
    sum_time = 0  # ---》 func1 --> 3 ---> 6
    
    def time_wait(func):
        # 登录成功后,可以使用的功能时长,单位 秒
        wait_time = 6
    
        def inner(*args, **kwargs):
            # 执行前时间
            start_time = time.time()
            res = func(*args, **kwargs)
            # 执行后时间
            end_time = time.time()
            global sum_time
            # 第一个函数进来后,func1 执行时长为3, func2 执行时长为3
            sum_time += (end_time - start_time)
            print(f'登录后执行的总时长: {sum_time}')
            # func1执行的时长 >= wait_time
            if sum_time >= wait_time:
                # 需要重新去登录
                login()
                sum_time = 0
            else:
                return res
    
        return inner
    
    
    @time_wait
    def func1():
        time.sleep(3)
    
    @time_wait
    def func2():
        time.sleep(3)
    
    # func1()
    # func2()
    #
    # # 此时总时长为6秒
    # func1()
    六、# 思考题(选做),叠加多个装饰器,加载顺序与运行顺序
    # @deco1 # index=deco1(deco2.wrapper的内存地址)
    # @deco2 # deco2.wrapper的内存地址=deco2(deco3.wrapper的内存地址)
    # @deco3 # deco3.wrapper的内存地址=deco3(index)
    # def index():
    #     pass
  • 相关阅读:
    8.8集训
    8.7集训
    8.6集训
    poj 2492
    埃氏筛法
    并查集板子
    2018级程序能力实训第二次上机考试
    网络流
    活动安排问题
    等价类
  • 原文地址:https://www.cnblogs.com/dingbei/p/12555744.html
Copyright © 2011-2022 走看看