一. 编写函数,(函数执行的时间用time.sleep(n)模拟)
1 import time
2 def index(x, y, z):
3 time.sleep(1)
4 print('index is run...')
5 return x, y, z
二. 编写装饰器,为函数加上统计时间的功能
1 import time
2 def timer(func):
3 def wrapper(*args, **kwargs):
4 start_time = time.time()
5 res = func(*args, **kwargs)
6 stop_time = time.time()
7 print(f'{func.__name__} run time: ', stop_time - start_time)
8 return res
9
10 return wrapper
11
12
13 @timer # index = wrapper = timer(index)
14 def index(x, y, z):
15 time.sleep(1)
16 print('index is run...')
17 return x, y, z
18
19
20 res = index(1, 2, 3)
21 '''
22 index is run...
23 index run time: 1.0003461837768555
24 '''
25 print(res) # (1, 2, 3)
三. 编写装饰器,为函数加上认证的功能
1 import time
2 username = 'egon'
3 password = '123'
4
5
6 def login():
7 inp_username = input("输入用户名>>:").strip()
8 inp_password = input("输入用户密码>>:").strip()
9 if inp_username == username and inp_password == password:
10 print("恭喜登录成功!")
11 return inp_username
12 else:
13 print("登录失败!")
14
15
16 def auth(func):
17 def wrapper(*args, **kwargs):
18 username = login()
19 if username:
20 res = func(*args, **kwargs)
21 return res
22 return wrapper
23
24 @auth # index = wrapper = auth(index)
25 def index(x, y, z):
26 time.sleep(1)
27 print('index is run...')
28 return x, y, z
29
30 res = index(1, 2, 3)
31 print(res)
四. 编写装饰器,为多个函数加上认证的功能(用户的账号密码来源于文件),要求登录成功一次,后续的函数都无需再输入用户名和密码
1 # 注意:从文件中读出字符串形式的字典,可以用eval('{"username":"egon","password":"123"}')转成字典格式
2 import time
3 import os
4
5 DB_PATH = r'db.txt'
6 login_state = None
7 def create_db():
8 if not os.path.isfile(DB_PATH):
9 with open(DB_PATH, mode='wt', encoding='utf-8') as f:
10 f.write('{"username":"egon","password":"123"}
{"username":"alex","password":"123"}
')
11
12
13
14 def read_db(name, pwd):
15 with open(DB_PATH, mode='rt', encoding='utf-8') as f:
16 for line in f:
17 res = line.strip()
18 if not res:
19 continue
20 current_user = eval(line)
21 username, password = current_user.values()
22 if name == username and password == pwd:
23 return name
24
25 def login():
26 create_db()
27
28 inp_username = input("输入用户名>>:").strip()
29 inp_password = input("输入用户密码>>:").strip()
30 res = read_db(inp_username, inp_password)
31 if res:
32 print("恭喜登录成功!")
33 global login_state
34 login_state = inp_username
35 return inp_username
36 else:
37 print("登录失败!")
38
39
40 def auth(func):
41 def wrapper(*args, **kwargs):
42 if not login_state:
43 login()
44 else:
45 res = func(*args, **kwargs)
46 return res
47 return wrapper
48
49 @auth # index = wrapper = auth(index)
50 def index(x, y, z):
51 time.sleep(1)
52 print('index is run...')
53 return x, y, z
54
55 @auth # home = wrapper = auth(home)
56 def home(x, y, z):
57 time.sleep(0.5)
58 print('home is run...')
59 return x, y, z
60
61 res = index(1, 2, 3)
62 print(res)
63
64 res = home(4, 5, 6)
65 print(res)
五. 编写装饰器,为多个函数加上认证功能,要求登录成功一次,在超时时间内无需重复登录,超过了超时时间,则必须重新登录
1 import time
2 import os
3
4 DB_PATH = r'db.txt'
5 login_state = None
6 def create_db():
7 if not os.path.isfile(DB_PATH):
8 with open(DB_PATH, mode='wt', encoding='utf-8') as f:
9 f.write('{"username":"egon","password":"123"}
{"username":"alex","password":"123"}
')
10
11
12
13 def read_db(name, pwd):
14 with open(DB_PATH, mode='rt', encoding='utf-8') as f:
15 for line in f:
16 res = line.strip()
17 if not res:
18 continue
19 current_user = eval(line)
20 username, password = current_user.values()
21 if name == username and password == pwd:
22 return name
23
24 def login(*args):
25 create_db()
26
27 inp_username = input("输入用户名>>:").strip()
28 inp_password = input("输入用户密码>>:").strip()
29 res = read_db(inp_username, inp_password)
30 if res:
31 print("恭喜登录成功!")
32 global login_state
33 login_state = inp_username
34 return inp_username
35 else:
36 print("登录失败!")
37
38
39 def auth(func):
40 def wrapper(*args, **kwargs):
41 if not login_state:
42 login()
43 else:
44 res = func(*args, **kwargs)
45 return res
46 return wrapper
47
48
49 @auth # index = wrapper = auth(index)
50 def index(*args):
51 time.sleep(1)
52 print('index is run...')
53 return args
54
55 @auth # home = wrapper = auth(home)
56 def home(*args):
57 time.sleep(0.5)
58 print('home is run...')
59 return args
60
61 func_dic = {
62 '0': ('登录', login),
63 '1': ('index', index),
64 '2': ('home', home),
65 }
66 def run(*args, **kwargs):
67 while True:
68 for key, value in func_dic.items():
69 print(f'({key}):{value[0]}', end=' ')
70 print()
71
72 start_time = time.time()
73 cmd = input('输入命令编号>>:').strip()
74 stop_time = time.time()
75 if stop_time - start_time >= 4:
76 print('长时间没操作, 需要重新登录.')
77 global login_state
78 login_state = None
79 continue
80 if not cmd.isdigit():
81 print('请输入数字')
82 continue
83 if cmd not in func_dic:
84 print("输入命令编号范围不正确")
85 func_dic[cmd][1](*args, **kwargs)
86
87 res = run(1, 2, 3)
88 print(res)
六. 选做题
1 # 思考题(选做),叠加多个装饰器,加载顺序与运行顺序,可以将上述实现的装饰器叠加起来自己验证一下
2 """
3 @deco1 # index=deco1(deco2.wrapper的内存地址)
4 @deco2 # deco2.wrapper的内存地址=deco2(deco3.wrapper的内存地址)
5 @deco3 # deco3.wrapper的内存地址=deco3(index)
6 def index():
7 pass
8 """
9 def decorator1(func):
10 def wrapper(*args, **kwargs):
11 print('from decorator1')
12 res = func(*args, **kwargs)
13 return res
14 return wrapper
15
16
17 def decorator2(func):
18 def wrapper(*args, **kwargs):
19 print('from decorator2')
20 res = func(*args, **kwargs)
21 return res
22 return wrapper
23
24
25 def decorator3(func):
26 def wrapper(*args, **kwargs):
27 print('from decorator3')
28 res = func(*args, **kwargs)
29 return res
30 return wrapper
31
32 @decorator1 # index = decorator1中的wrapper的内存地址 = decorator1(decorator2(decorator3(index)) )
33 @decorator2 # decorator2中的wrapper的内存地址 = decorator2(decorator3(index))
34 @decorator3 # decorator3中的wrapper的内存地址 = decorator3(index)
35 def index():
36 print('from index')
37
38 index()
39 '''
40 from decorator1
41 from decorator2
42 from decorator3
43 from index
44 '''
45 # 加载顺序: index > decorator3 > decorator2 > decorator1
46 # 运行顺序: decorator1 > decorator2 > decorator3 > index