#装饰器,语法糖 @函数名
import time
#简单装饰器
def timer(F):
def inner():
start_time = time.time()
F()
end_time = time.time()
print("耗时%s" % (end_time - start_time))
return inner
@timer# 相当于 test = timer(test) 此时test变量等于 inner() 之后执行直接使用函数变量 test10 ,相当于执行inner()函数
def test10():
for i in range(3):
print(i)
test10()
"""
0
1
2
耗时9.059906005859375e-06
"""
#传参
def timer2(F):
def inner(*args, **kwargs):
start_time = time.time()
F(*args, **kwargs)
end_time = time.time()
print("耗时%s" % (end_time - start_time))
return inner#这里不能加括号
@timer2# 相当于 test11 = timer(test11) 此时test变量等于 inner() 之后执行直接使用函数变量 test11 ,相当于执行inner()函数
def test11(y):
for i in range(y):
print(i)
test11(3)
"""
0
1
2
耗时9.059906005859375e-06
"""
#带返回值
def timer3(F):
def inner(*args, **kwargs):
start_time = time.time()
msg = F(*args, **kwargs)#保存被装饰函数返回
end_time = time.time()
print("耗时%s" % (end_time - start_time))
return msg#返回被装饰函数结果
return inner
@timer3
def test11(y):
for i in range(y):
print(i)
return i
print('test11', test11(3))
"""
0
1
2
耗时7.867813110351562e-06
test11 2
"""
from functools import wraps
#装饰器函数的信息
def wrapper(Funt):
@wraps(Funt)#保证被装饰函数拥有原来的属性
def inner(*args, **kwargs):
"""
装饰器
:param args:
:param kwargs:
:return:
"""
msg = Funt()
return msg
return inner
@wrapper
def test2():
"""
函数说明
:return:
"""
pass
print(test2.__name__)#输出函数名
print(test2.__doc__)#输出函数说明
#带参数的装饰器
# flag = True
flag = False
def wrapper2(flag1):
def wrapper1(Funt):
@wraps(Funt)
def inner(*args, **kwargs):
# global flag
if flag:
"""装饰"""
msg = Funt('装饰')
else:
"""不装饰"""
msg = Funt("不装饰")
return msg
return inner
return wrapper1
@wrapper2(flag)#执行顺序:1、wrapper2(flag) == wrapper1, 得到的结果是@wrapper1
def test3(a):
print('a', a)
test3()#a 不装饰
#多个装饰器装饰一个函数
def wrapper3(F):
def inner1():
print("wrapper3, before")
F()
print("wrapper3, after")
return inner1
def wrapper4(F):#F = inner1()
def inner2():
print("wrapper4, before")
F()
print("rapper4, after")
return inner2
@wrapper4#2、test4 = wrapper4(test4) 实参test4是新变量test4,实际是inner1()
@wrapper3#1、执行 test4 = wrapper3(test4),test4 = inner1()
def test4():
print("test4")
test4()
#执行结果
"""
wrapper4, before
wrapper3, before
test4
wrapper3, after
rapper4, after
"""
#练习:编写装饰器,实现注册、登陆,登陆成功一次,后续函数无需输入账号密码
status = 0
def register():
name = input('用户名:')
password = input('密码:')
with open('./1.txt', mode='a+') as file:
file.seek(0)
while True:
line = file.readline()
if line:
if name == line.split(',')[0]:
return "用户名已存在"
else:
break
msg = name + ',' + password + '\n'
file.write(msg)
global status
status = 1
return "注册成功"
def wrapper(F):
def inner(*args, **kwargs):
global status
if status == 0:
name = input('请输入登陆用户')
password = input('请输入密码')
with open('./1.txt', mode='r') as file:
while True:
line = file.readline().strip()
if line:
req_msg = name + ',' + password
if line == req_msg:
print('登陆成功')
status = 1
msg = F(*args, **kwargs)
return msg
else:
break
if status == 0:
print('用户名密码不正确')
return False
else:
msg = F(*args, **kwargs)
return msg
return inner
@wrapper
def index_1():
print("首页一")
@wrapper
def index_2():
print('首页二')
@wrapper
def index_3():
print('首页三')
#print(register())#注册,成功也不用重新登录
index_1()
index_3()
index_2()
#练习2:给函数加日志,记录函数的名称、时间
import time
def wrapper5(F):
def inner(*args, **kwargs):
with open("log", 'a', encoding='utf-8') as f1:
f1.write("%s 函数在 %s 执行\n" % (F.__name__, time.asctime()))
ret = F(*args, **kwargs)
return ret
return inner
@wrapper5
def test1():
pass
@wrapper5
def test2():
pass
test1()
test2()
#练习3:设置登陆,分两个平台,相同平台登陆成功可成功访问,不同平台需重新登陆,成功则平台下所有页面均可访问,失败三次结束
status_list = {'name': None, 'user_status': False, 'user2_status': False}
def login_out(ags):
def login(F):
@wraps(F)
def inner(*args, **kwargs):
if status_list['%s_status' % ags]:
ret = F()
return ret
else:
status_list['user_status'] = False
status_list['user2_status'] = False
i = 1
while i < 4:
username = input('用户名:').strip()
password = input('密码:').strip()
with open("%s_info" % (ags), encoding='utf-8') as f1:
for line in f1:
user_list = line.strip().split(',')
if username == user_list[0] and password == user_list[1]:
print("登陆成功")
status_list['name'] = username
status_list['%s_status' % ags] = True
ret = F()
return ret
print("用户名或密码错误,还剩%s次" % (3-i))
i += 1
return inner
return login
@login_out('user')
def index():
print("首页")
print("欢迎%s" % (status_list['name']))
@login_out('user2')
def knowledge():
print("知识区欢迎%s" % (status_list['name']))
@login_out('user2')
def kichiku():
print("鬼畜区欢迎%s" % (status_list['name']))
def choose():
while True:
dic_s = {
1: index,
2: knowledge,
3: kichiku
}
print("""
1、看剧
2、听歌
3、学习
""")
ch = input("请选择:").strip()
if ch.isdigit():
ch = int(ch)
if 0 < ch <= len(dic_s):
dic_s[ch]()
else:
print("选项有误")
else:
print("输入有误")
choose()