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()

![Python“三大器”之装饰器2[Python常见问题]](https://www.zixueka.com/wp-content/uploads/2023/10/1696831224-a36ecddd9515072.jpg)
