装饰器
装饰器就像我们穿长裤,在不影响内裤作用的前提下,给我们的身子提供了保暖的功效。装饰器的作用就是为已经存在的对象添加额外的功能。
作用:让其他函数在不需要做任何代码变动的前提下增加额外功能,装饰器的返回值也是一个函数对象。
最简单的装饰器
# 最简单的装饰器
# 为函数添加运行时间的功能
import time
def timer(funcname):
def wrapper():
start = time.time()
funcname()
stop = time.time()
print("函数运行时间为%f" % (stop - start))
return wrapper
@timer # home = timer(home)
def home():
time.sleep(1)
print("welcome to index page")
home() # 未改变函数原先的调用方式
添加传入参数
import time
def timer(func): # 函数运行时间装饰器
def wrapper(*args, **kwargs):
start1 = time.time()
res = func(*args)
stop1 = time.time()
print("run time is %f" % (stop1 - start1))
return res
return wrapper
@timer # foo = timmer(foo)
def foo():
time.sleep(1)
print("welcome to oldboy")
@timer
def home(name): # home = timer(home)
time.sleep(1)
print("welcome to %s home" % name)
@timer # home = timer(home)
def tell(name, age):
time.sleep(1)
print("my name is %s ,i am %s years old" % (name, age))
# 函数调用阶段
foo()
print("--------------")
home('zou')
print("--------------")
tell("chen", "18")
有参装饰器
# 有参装饰器
# 参数是选择认证方式
def auth2(auth_type="file"): # 默认认证方式为文件判断
def auth(func):
def wrapper(*args, **kwargs):
if auth_type == "file":
count = 0
while count < 3: # 输入用户名和密码进行登陆
username = input("username:>>")
password = input("password:>>")
if username == "zou" and password == "123":
print("登陆成功")
res = func(*args, **kwargs) # 执行原函数
return res
else:
count += 1
if count == 3:
print("输错三次了,程序退出")
elif auth_type == "sql":
print("还没学sql认证")
return wrapper
return auth
@auth2() # home = auth(home)
def home(name):
print("its in %s's house" % name)
home("zou") # 主函数入口
为函数添加认证装饰器,输错三次锁定用户
有三个txt文件,
blackname.txt-->存放黑名单
info.txt-->存放所有用户信息和密码
status.txt-->保存用户登陆状态,默认写入
status = {"user": None, "login": False}
# 有参装饰器为函数添加认证功能,
# 用户信息来源是文件或者数据库,三次验证失败锁定用户
def confirm2(auth_type = "file"):
def confirm(func):
def wrapper(*args, **kwargs):
if auth_type == "file": # 判断哪种方式认证
with open("status.txt") as sfile:
data = sfile.readline().strip()
user_status = eval(data) # 拿到用户登陆状态
if user_status["login"] == True:
func(*args, **kwargs) # 用户已经登陆过
else:
username = input("username:>>")
with open("blackname.txt") as bfile: # 判断是否在黑名单
for line in bfile:
if username in line.strip():
print("用户被锁定")
return 0
with open("info.txt") as ifile: # 判断是否在用户数据库
status = {"user": None, "login": False}
for line in ifile:
_username, _password = line.strip().split()
if username == _username:
count = 0
while count < 3:
password = input("passward:>>") # 输入密码判断
if password == _password:
print("登陆成功")
func(*args, **kwargs) # 函数执行
status["user"] = username
status["login"] = True
with open("status.txt", "w") as sfile: # 写入登陆状态
sfile.write(str(status))
break
else:
count += 1
continue
if count == 3:
with open("blackname.txt", "a") as bfile:
bfile.write(username+"
")
print("连续输错三次,用户被锁定")
elif auth_type == "sql":
print("还没学sql")
return wrapper
return confirm
@confirm2()
def home(name):
print("welcome to %s home"% name)
@confirm2()
def index(name):
print("欢迎来到%s主页程序" % name)
# 函数调用
home("zou")
index("zou")