一:编写函数,(函数执行的时间用time.sleep(n)模拟) 二:编写装饰器,为函数加上统计时间的功能 三:编写装饰器,为函数加上认证的功能 四:编写装饰器,为多个函数加上认证的功能(用户的账号密码来源于文件),要求登录成功一次,后续的函数都无需再输入用户名和密码 注意:从文件中读出字符串形式的字典,可以用eval('{"name":"egon","password":"123"}')转成字典格式 五:编写装饰器,为多个函数加上认证功能,要求登录成功一次,在超时时间内无需重复登录,超过了超时时间,则必须重新登录 六:选做题 # 思考题(选做),叠加多个装饰器,加载顺序与运行顺序,可以将上述实现的装饰器叠加起来自己验证一下 # @deco1 # index=deco1(deco2.wrapper的内存地址) # @deco2 # deco2.wrapper的内存地址=deco2(deco3.wrapper的内存地址) # @deco3 # deco3.wrapper的内存地址=deco3(index) # def index(): # pass
# 一:编写函数,(函数执行的时间用time.sleep(n)模拟) ''' import time # 源码 def func(): time.sleep(3) # 单位: 秒 func() ''' # 二:编写装饰器,为函数加上统计时间的功能 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() # 三:编写装饰器,为函数加上认证的功能 # 全局变量: 用于记录是否有用户登录 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() # 四:编写装饰器,为多个函数加上认证的功能(用户的账号密码来源于文件),要求登录成功一次,后续的函数都无需再输入用户名和密码 # 注意:从文件中读出字符串形式的字典,可以用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 # 五:编写装饰器,为多个函数加上认证功能,要求登录成功一次,在超时时间内无需重复登录,超过了超时时间,则必须重新登录 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 ''' def wrapper1(func): def inner1(*args, **kwargs): res = func(*args, **kwargs) return res return inner1 def wrapper2(func): def inner2(*args, **kwargs): res = func(*args, **kwargs) return res return inner2 def wrapper3(func): def inner3(*args, **kwargs): res = func(*args, **kwargs) return res return inner3 @wrapper1 @wrapper2 @wrapper3 def index(): pass '''