首页 > 代码库 > Python基础-装饰器

Python基础-装饰器

待更新:

 

 

 

装饰器实例

程序需求:

  1. 在不改变func_1函数(程序)定义和调用方式的基础上,添加计时和用户认证功能
  2. 用户认证要求:
  • 用户最多尝试3次登陆
  • 当存在的用户登陆失败3次后,锁定该用户,限制登陆

程序代码:

技术分享
 1 import time
 2 
 3 
 4 def run_timer(func):        #计时器函数
 5     def wrapper(*args, **kwargs):       #装饰器
 6         start = time.time()     #开始计时
 7         func(*args, **kwargs)       #运行程序
 8         end = time.time()       #停止计时
 9         print(Run time is %ss % (end - start))        #打印程序运行时长
10 
11     return wrapper
12 
13 
14 def identiy():
15     """用户登陆验证程序
16         最多可尝试3次登陆
17         当某一存在的用户输入错误密码3次后,锁定该用户,限制登陆"""
18     with open(account_bak, r+) as f_account, open(locked_list, a+) as f_locked:
19         f = 0               #程序返回值变量
20         l = []              #被锁定用户列表
21         user_input = []     #输入错误密码的用户名列表
22         count = 0           # 登陆次数计数器
23         flag = True         # 登陆循环控制开关
24         while flag and count < 3:
25             name = input(Please input username:)  # 输入用户名
26             pwd = input(Please input password:)  # 输入用户密码
27             f_locked.seek(0)        #"a+"模式打开后,文件位置位于末尾,要遍历文件内容,需要将指针移至文件起始位置
28             for locked_user in f_locked:        #将被锁定用户名单写入列表
29                 l.append(locked_user.strip())
30             if name in l:
31                 print(This user has been locked!)     #如果当前欲登陆用户在被锁定列表中,提示并重新输入登陆信息
32             else:
33                 user_input.append(name)     #将当前输入的用户名加入到列表
34                 f_account.seek(0)  #循环前将文件位置移至起始位置
35                 for line in f_account:      #遍历用户登陆数据文件
36                     s = eval(line)          #将该文件的内容转换为字典格式
37                     if name == s[name] and pwd == s[password]:     #判断用户名和密码是否正确
38                         print(Authenticate successful)        #用户名和密码匹配,认证成功,结束循环,并将f=1返回
39                         f = 1
40                         flag = False
41                         break
42                 if f == 1:      #用户名和密码不匹配,提示用户输入错误
43                     continue
44                 print(Wrong name or password!)
45                 count += 1      #错误次数加1,当count等于3时,结束循环
46         if len(user_input) == 3:        #如果该列表长度等于3,说明用户3次登陆均失败
47             if user_input[0] == user_input[1] == user_input[2]:     #判断3次登陆是否时同一用户名
48                 f_account.seek(0)       #重置文件位置为起始位置
49                 l = []      #新建空列表,存放用户登陆文件中的用户名信息
50                 for line in f_account:      #遍历用户登陆文件
51                     s = eval(line)           #将行内容转换为字典格式
52                     l.append(s[name])     #将用户名加入到列表
53                 if user_input[0] in l:      #判断登陆失败的用户名是否在上述列表中
54                     print(This user has been locked!)     #提示用户将锁定该登陆名
55                     f_locked.write(user_input[0] + \n)    #将该登录名加入锁定文件
56                     f_locked.flush()        #实时刷新文件
57     return f
58 
59 
60 def auth(source):
61     """用户登陆认证程序的装饰器"""
62     def auth_main(func):
63         def wrapper(*args, **kwargs):
64             if source == file:        #判断认证来源类型是否为‘file’
65                 if (identiy() == 1):        #调用用户登陆认证程序
66                     res = func(*args, **kwargs)     #运行被装饰的程序
67                     return res
68             elif source == ldap:      #另外一种认证来源类型
69                 def wrapper_2(*args, **kwargs):
70                     print(Nothing here!)
71                     pass
72         return wrapper
73     return auth_main
74 
75 
76 @auth(source = file)      #将用户登陆认证功能装饰程序‘func_1’
77 @run_timer                  #将程序计时功能装饰程序‘func_1’
78 def func_1():               #被装饰程序
79     time.sleep(1)
80     print(This is function_1)
81 
82 
83 func_1()        #调用被装饰程序
计时+登陆认证 装饰器

验证过程:

1. account文件:存放用户登陆数据

技术分享

2. locked_list文件:存放被锁定用户名

  当前为空

技术分享

3. 尝试登陆正确的用户

技术分享

4. 尝试不同用户登陆失败

技术分享

5. 尝试同一用户登陆失败

技术分享

6. 尝试同一用户登陆失败,但该用户本身不存在

技术分享

 

 

 

 

 

Python基础-装饰器