补充1:装饰器

【知识点】

1、装饰器:完全遵循开放封闭原则

  在不改变原函数的代码以及调用方式的前提下,为其增加新的功能。

(1)开放封闭原则

    开放:对代码的拓展

    封闭:对源码的修改是封闭的

 1 # 版本一 写一些代码测试下index这个函数的执行效率
 2 # import time
 3 #
 4 # def index():
 5 #     '''有很多代码'''
 6 #     time.sleep(3) # 模拟网络延迟挥着代码效率
 7 #     print('欢迎登陆博客园首页')
 8 #
 9 # def dairy():
10 #     '''有很多代码'''
11 #     time.sleep(3) # 模拟网络延迟挥着代码效率
12 #     print('欢迎登陆日记首页')
13 #
14 # # 测试部分
15 # start_time=time.time()
16 # index()
17 # end_time=time.time()
18 # print(end_time-start_time)
19 #
20 # start_time=time.time()
21 # dairy()
22 # end_time=time.time()
23 # print(end_time-start_time)
24 # 版本一问题:如果测试别人的代码,必须重新赋值粘贴
25 
26 # 版本二:利用函数,解决代码重复的问题
27 # import time
28 #
29 # def index():
30 #     '''有很多代码'''
31 #     time.sleep(3) # 模拟网络延迟挥着代码效率
32 #     print('欢迎登陆博客园首页')
33 #
34 # def dairy():
35 #     '''有很多代码'''
36 #     time.sleep(3) # 模拟网络延迟挥着代码效率
37 #     print('欢迎登陆日记首页')
38 #
39 # def timmer(f):
40 #     start_time=time.time()
41 #     f()
42 #     end_time=time.time()
43 #     print(end_time-start_time)
44 #
45 # timmer(index)
46 # 版本二问题:原来index函数源码没有变化,给原函数添加了一个新的功能测试原函数执行的效率的功能
47 # 没有满足开放封闭原则,原函数的调用方式改变了
48 
49 # 版本三:不能改变原函数的调用方式
50 import time
51 
52 def index():
53     '''有很多代码'''
54     time.sleep(3) # 模拟网络延迟挥着代码效率
55     print('欢迎登陆博客园首页')
56 
57 def timmer(f):
58     def inner():
59         start_time = time.time()
60         f()
61         end_time=time.time()
62         print(end_time-start_time)
63     return inner
64 
65 index=timmer(index)
66 index()
装饰器前奏

  装饰器就是一个函数

(2)装饰器的标准形式

 1 # 版本四:python做了一个优化,提出了一个语法糖的概念
 2 import time
 3 
 4 # 装饰器写在前面
 5 def timmer(f):
 6     def inner():
 7         start_time = time.time()
 8         f()
 9         end_time=time.time()
10         print(f'测试本函数的执行效率{end_time-start_time}')
11     return inner
12 
13 @timmer    # index=timmer(index)
14 def index():
15     '''有很多代码'''
16     time.sleep(3) # 模拟网络延迟或者代码效率
17     print('欢迎登陆博客园首页')
18 
19 @timmer   # dairy=timmer(dairy)
20 def dairy():
21     '''有很多代码'''
22     time.sleep(3) # 模拟网络延迟或者代码效率
23     print('欢迎登陆日记首页')
24 
25 dairy()

  详细过程:

(3)被装饰函数的返回结果问题

 1 # 加上装饰器不应该改变原函数的返回值,做如下操作:
 2 import time
 3 
 4 def timmer(f):
 5     def inner():
 6         start_time = time.time()
 7         r=f()  # 将执行某个函数返回的结果赋给r
 8         end_time=time.time()
 9         print(f'测试本函数的执行效率{end_time-start_time}')
10         return r # r作为原始函数的返回值
11     return inner
12 
13 @timmer    # index=timmer(index)
14 def index():
15     '''有很多代码'''
16     time.sleep(3) # 模拟网络延迟或者代码效率
17     print('欢迎登陆博客园首页')
18 
19 @timmer   # dairy=timmer(dairy)
20 def dairy():
21 
22     '''有很多代码'''
23     time.sleep(3) # 模拟网络延迟或者代码效率
24     print('欢迎登陆日记首页')
25     return 666
26 
27 ret=dairy()
28 print(ret)  # 666  实现装饰后依然返回函数原本的返回值

(4)装饰器下的函数传参问题

 1 # 装饰器下的函数传参问题
 2 import time
 3 
 4 def timmer(f):
 5     def inner(*args,**kwargs):   # 这里既要接收一个参数,又要接收两个参数
 6         # 函数的定义:*聚合  args=('taibai',30)
 7         
 8         start_time = time.time()
 9         r=f(*args,**kwargs)  # 将执行某个函数返回的结果赋给r
10         # 函数的执行:*打散  f(*args)=f(*('taibai',30)——>f('taibai',30)
11         
12         end_time=time.time()
13         print(f'测试本函数的执行效率{end_time-start_time}')
14         return r # r作为原始函数的返回值
15     return inner
16 
17 @timmer   # dairy=timmer(dairy)
18 def dairy(name):
19     '''有很多代码'''
20     time.sleep(3) # 模拟网络延迟或者代码效率
21     print(f'欢迎{name}登陆日记首页')
22     return 666
23 
24 @timmer    # index=timmer(index)
25 def index(name,age):
26     '''有很多代码'''
27     time.sleep(3) # 模拟网络延迟或者代码效率
28     print(f'欢迎{age}岁的{name}登陆博客园首页')
29 
30 ret=dairy('alex')  # 这里的dairy()其实是inner()
31 print(ret)  # 666  实现装饰后依然返回函数原本的返回值
32 ret1=index('taibai',30)  # inner('taibai',30)

(5)最终版的标准版装饰器

1 # 最终版的标准版装饰器
2 def wrapper(f):
3     def inner(*args,**kwargs):
4         '''添加额外的功能:执行被装饰函数之前的操作'''
5         f(*args,**kwargs)
6         '''添加额外的功能:执行被装饰函数之后的操作'''
7         return ret
8     return inner

2、装饰器的应用

(1)登录认证

 1 # 登录认证
 2 def login():
 3     print('请完成登录功能')
 4     username = input('请输入用户名:')
 5     password = input('请输入密码:')
 6     if username == 'taibai' and password == '123':
 7         print('登录成功')
 8         status_dict['username'] = username
 9         status_dict['status'] = True
10         return True
11     else:
12         print('登录失败')
13         return False
14 
15 
16 def register():
17     pass
18 
19 status_dict = {
20     'username': None,
21     'status': False,
22 }
23 def auth(f):
24     '''
25     你的装饰器完成:访问被装饰函数之前,写一个三次登陆认证的功能。
26     登录成功:让其访问被装饰的函数,登录没有成功,不让访问。
27     :return:
28     '''
29     def inner(*args,**kwargs):
30         '''访问函数之前的操作:功能'''
31         if status_dict['status']:
32             ret=f(*args,**kwargs)
33             '''访问函数之后的操作:功能'''
34             return ret
35         else:
36             res=login()
37             if res:
38                 inner(*args, **kwargs)
39     return inner
40 
41 @auth
42 def article():
43     print('欢迎访问文章的页面')
44 
45 @auth
46 def comment():
47     print('欢迎访问评论页面')
48 
49 @auth
50 def dairy():
51     print('欢迎访问日记页面')
52 
53 article()
54 comment()
55 dairy()

时间:2020-02-24    22:08:02

posted @ 2020-02-24 22:08  红叶楠木  阅读(110)  评论(0)    收藏  举报