Python“三大器”之装饰器2
装饰器
1、叠加装饰器
(1)什么是叠加装饰器
在同一个被装饰对象中,添加多个装饰器并执行
(2)为什么要使用叠加装饰器
不使用叠加装饰器会导致代码冗余,结构不清晰,可扩展性差,所以最好每一个新的功能都应该写一个新的装饰器
(3)怎么使用叠加装饰器
使用方式:
@装饰1
@装饰2
@装饰3
def 被装饰对象():
pass
例子1:
我的需求:为被装饰对象,添加统计与登录认证功能
import time user_info = { "user": None } # 登陆功能 def login(): username = input("请输入您的账户:").strip() password = input("请输入您的密码:").strip() with open("dir/passwd.txt", "r", encoding="utf-8") as f: # 我在同级目录下创建了一个dir目录,然后在目录下创建了一个passwd的文本文档,里面内容为tank:123,然后回车另起一行保存 info = f.readline().strip(" ").split(":") name, pwd = info if username == name and password == pwd: print("登陆成功...") user_info["user"] = username else: print("登录失败...") # 登录认证装饰器 def login_auth(func): def inner1(*args, **kwargs): # 登录认证功能 if user_info.get("user"): res = func(*args, **kwargs) return res else: login() return func(*args, **kwargs) # 无论inner1中出现任何判断,最后都要返回“调用后的被装饰对象”:func(*args, **kwargs) return inner1 ##### 注意:登陆这里无论inner1中出现任何判断,最后都要返回“调用后的被装饰对象”:func(*args, **kwargs) # 统计时间装饰器 def time_record(func): def inner2(*args, **kwargs): print("开始统计...") start_time = time.time() res = func(*args, **kwargs) end_time = time.time() print(f"消耗时间为{end_time - start_time}") return res return inner2 # 装饰顺序:先装饰time_record,再装饰login_auth @login_auth # inner1 = login_auth(inner2) @time_record # inner2 = time_record(download_movie) def download_movie(): print("电影开始下载...") time.sleep(3) print("电影下载完成!") return "gtwz.mp4" # 执行顺序:先执行login_auth,再执行time_record # 只统计下载电影的时间 login() # 先调用用户登录,模拟用户已登录 download_movie()