装饰器进阶

装饰器进阶

 

  • 带参数的装饰器

 1 def outer(flag):
 2     def timer(func):
 3         def inner(*args,**kwargs):
 4             if flag:
 5                 print('''执行函数之前要做的''')
 6             re = func(*args,**kwargs)
 7             if flag:
 8                 print('''执行函数之后要做的''')
 9             return re
10         return inner
11     return timer
12 
13 @outer(False)   ##   等同于 :@ + timer(func)
14 def func():
15     print(111)
16 
17 func()
  • 多个装饰器装饰一个函数

 1 def wrapper1(func):
 2     def inner1():
 3         print('wrapper1 ,before func')##2
 4         func()       ##3
 5         print('wrapper1 ,after func')##4
 6     return inner1
 7 
 8 def wrapper2(func):
 9     def inner22():
10         print('wrapper2 ,before func')   ##  1
11         func()
12         print('wrapper2 ,after func')###  5
13     return inner2
14 
15 @wrapper2   ## f = wrapper2(f)  里面的f是 inner1,左边的是inner2
16 @wrapper1   ## f  = wrapper1(f) 里面f的是f()函数,  左边的是inner1
17 def f():
18     print('in f')
19 
20 f()

wraps版

1 from functools import wraps
2 
3 def deco(func):
4     @wraps(func) #加在最内层函数正上方
5     def wrapper(*args,**kwargs):
6         return func(*args,**kwargs)
7     return wrapper
8 
9 装饰器的固定格式--wraps版

作业两题

 1 7.编写装饰器,为多个函数加上认证的功能(用户的账号密码来源于文件),
 2 要求登录成功一次(三次机会),后续的函数都无需再输入用户名和密码
 3 
 4 dic = {
 5     'username':None,   ####  g构建一个字典存放用户名以及函数状态
 6     'status':False,
 7 }
 8 
 9 def wrapper(func):
10     def inner(*args, **kwargs):
11         if dic['status']:
12             ret = func(*args, **kwargs)  ### 如果为True就免登录,如为false,就有认证功能。
13             return ret
14         else:
15             i = 0
16             while i < 3:
17                 username = input('请输入用户名:').strip()
18                 password = input('请输入密码:').strip()
19                 with open('register_msg',encoding='utf-8') as f1:
20                     for j in f1:
21                         j_li = j.strip().split()  # ['张三','123']
22                         if username == j_li[0] and password == j_li[1]:
23                             dic['username'] = username
24                             dic['status'] = True
25                             ret = func(*args, **kwargs)
26                             return ret
27                     else:
28                         print('账号或者密码错误,请重新输入%s机会' % (2-i))
29                         i += 1
30 
31 
32     return inner
33 
34 
35 @wrapper
36 def article():
37     print('文章')
38 
39 @wrapper
40 def diary():
41     print('日记')
42 
43 @wrapper
44 def comment():
45     print('评论')
46 
47 @wrapper
48 def file():
49     print('文件')
50 
51 article()
52 diary()
53 comment()
54 file()

四平台账号认证功能

 

 1 在编写装饰器,为多个函数加上认证的功能(用户的账号密码来源于文件),要求登录成功一次,后续的函数都无需再输入用户名和密码。
 2 这个作业之上进行升级操作:
 3 设置两套密码,一套为微信账号密码,一套为qq账号密码保存在文件中。
 4 设置四个函数,分别代表
 5 京东首页,京东超市,淘宝首页,淘宝超市。
 6 循环打印四个选项:东首页,京东超市,淘宝首页,淘宝超市。
 7 供用户选择,用户输入选项后,执行该函数,四个函数都加上认证功能,只要登陆成功一次,在选择其他函数,后续都无需输入用户名和密码。
 8 相关提示:用带参数的装饰器。装饰器内部加入判断,验证不同的账户密码。
 9 
10 dic = {
11     'username':None,
12     'status':False,
13 }
14 
15 
16 def login(flag):
17     def wrapper(func):
18         def inner(*args, **kwargs):
19             if dic['status']:
20                 ret = func(*args, **kwargs)
21                 return ret
22             else:
23                 i = 0
24                 while i < 3:
25                     username = input('请输入用户名(用%s账号):' % flag).strip()
26                     password = input('请输入密码:').strip()
27                     with open('user_pwd',encoding='utf-8') as f1:
28                         msg_dic = eval(f1.readline())
29         ###!!! {'微信': {'password': '123', 'username': '老男孩'}, 'qq': {'password': '123', 'username': '老男孩1'}}
30                         if username == msg_dic[flag]['username'] and \
31                                 password == msg_dic[flag]['password']:
32                             dic['username'] = username
33                             dic['status'] = True
34                             ret = func(*args, **kwargs)
35                             return ret
36                         else:
37                             print('您输入的用户或者密码错误,请重新输入,还有%s次机会' % (2-i))
38                             i += 1
39         return inner
40     return wrapper
41 
42 
43 
44 
45 @login('微信')
46 def taobao_home():
47     print('淘宝首页')
48 
49 @login('微信')
50 def taobao_shop():
51     print('淘宝超市')
52 
53 @login('qq')
54 def jingdong_home():
55     print('京东首页')
56 
57 @login('qq')
58 def jingdong_shop():
59     print('京东超市')
60 
61 choice_dict = {
62     1: taobao_home,
63     2: taobao_shop,
64     3: jingdong_home,
65     4: jingdong_shop,
66 }
67 
68 while True:
69     print('1 淘宝首页\n2 淘宝超市\n3 京东首页\n4 京东超市')
70     choice_num = input('请选择输入的序号:').strip()
71     if choice_num.isdigit():
72         choice_num = int(choice_num)
73         if 0 < choice_num <= len(choice_dict):
74             choice_dict[choice_num]()
75         else:
76             print('请输入范围内的序号')
77     else:
78         print('您输入的有非法字符,请重新输入')
View Code

 

posted on 2018-04-03 20:31  弃疾  阅读(119)  评论(0)    收藏  举报

导航