装饰器

一、基本概念:

装饰器:本质上就是函数,功能是为其它函数添加附加功能

原则:

       1、不修改被修饰函数的源代码

       2、不修改被修饰函数的调用方式

        装饰器=高阶函数+嵌套函数+闭包

使用函数计算加和程序:

 1 import time
 2 def cal(l):
 3     start_time=time.time()
 4     res=0
 5     for i in l:
 6         time.sleep(0.1)
 7         res+=i
 8     stop_time=time.time()
 9     print('函数运行的时间是%s' %(stop_time-start_time))
10     return res
11 print(cal(range(50)))
12 # 函数运行的时间是5.022611856460571
13 # 1225

二、高阶函数定义:

      1.函数接收的参数是一个函数名
      2.函数的返回值是一个函数名
      3.满足上述条件任意一个,都可称之为高阶函数

         定义一示例:

 1 import time
 2 def foo():
 3     time.sleep(2)
 4     print('helloworld!')
 5 def test(func):
 6     print(func)
 7     start_time=time.time()
 8     func()
 9     stop_time=time.time()
10     print('程序运行的时间是%s' %(stop_time-start_time))
11 test(foo)#--------修改了foo的调用方式
12 # <function foo at 0x015F1FA8>
13 # helloworld!
14 # 程序运行的时间是2.0001471042633057

        定义二示例:

 1 import time
 2 def foo():
 3     time.sleep(2)
 4     print('from the foo')
 5 #多运行一步,不合格
 6 def timer(func):
 7     print(func)
 8     start_time=time.time()
 9     func()
10     stop_time=time.time()
11     print('程序运行的时间是%s' %(stop_time-start_time))
12     return func
13 foo=timer(foo)
14 # <function foo at 0x026C1FA8>
15 # from the foo
16 # 程序运行的时间是2.000005006790161

          高阶函数无法满足不改变函数调用方式的需求:

函数闭包装饰器基本实现:

       1、实现一个装饰器最基本的架子:

1 #这是实现一个装饰器最基本的框架
2 def timer(func):
3     def wrapper():
4         func()
5     return wrapper

       2、含有参数的装饰器框架:

1 def timer(func):
2     def wrapper(*args,**kwargs):
3         func(*args,**kwargs)
4     return wrapper

        3、含有计数功能的装饰器:

1 import time
2 def timer(func):
3     def func(*args,**kwargs):
4         start_time=time.time()
5         func(*args,*kwargs)
6         stop_time=time.time()
7         print('函数%s, 运行时间为%s' %(func(), stop_time-start_time))
8     return wrapper

        4、装饰器含有返回值:

1 import time
2 def timer(func):
3     def func(*args,**kwargs):
4         start_time=time.time()
5         res=func(*args,*kwargs)
6         stop_time=time.time()
7         print('函数%s, 运行时间为%s' %(func(), stop_time-start_time))
8         return res
9     return wrapper

        5、语法糖案例:利用装饰器计算函数运行时间

 1 import time
 2 def timmer(func):
 3      def wrapper():
 4         start_time=time.time()
 5         func()
 6         stop_time=time.time()
 7         print('运行时间是%s' %(stop_time-start_time))
 8      return wrapper
 9 
10 @timmer  #test=timmer(test)
11 def test():
12     time.sleep(2)
13     print('test函数运行完毕')
14 test()
15 # test函数运行完毕
16 # 运行时间是2.0002970695495605

      6、使用装饰器计算加和时间:

 1 import time
 2 def timmer(func):
 3      def wrapper():
 4         start_time=time.time()
 5         func()
 6         stop_time=time.time()
 7         print('运行时间是%s' %(stop_time-start_time))
 8      return wrapper
 9 
10 @timmer
11 def calc(array):
12     res=0
13     for i in array:
14         res+=i
15     return res
16 calc(range(10))
17 #原代码没有修改

      7、装饰器应用案例:

         函数闭包加上返回值

 1 import time
 2 def timmer(func):
 3      def wrapper():
 4         start_time=time.time()
 5         res=func()
 6         stop_time=time.time()
 7         print('运行时间是%s' %(stop_time-start_time))
 8         return res
 9      return wrapper
10 
11 @timmer  #test=timmer(test)
12 def test():
13     time.sleep(2)
14     print('test函数运行完毕')
15     return '这是test的返回值'
16  res=test()#-----接收函数运行返回值
17 print(res)
18 # test函数运行完毕
19 # 运行时间是2.0009660720825195
20 # 这是test的返回值

       验证功能装饰器:

 1 #逐条输入验证装饰器:
 2 def auth_func(func):
 3     def wrapper(*args,**kwargs):
 4         username=input('用户名:')
 5         password=input('密码:')
 6         if username=='alex' and password=='123':
 7             res=func(*args,**kwargs)
 8             return res
 9         else:
10             print('用户名或密码错误')
11     return wrapper
12 @auth_func
13 def index():
14     print('欢迎来到京东主页')
15 @auth_func
16 def home(name):
17     print('欢迎回来,%s' %name)
18 @auth_func
19 def shopping_car(name):
20     print('%s的购物车里有%s %s' %(name,'','服装'))
21 index()
22 home('alex')
23 shopping_car('alex')

        功能化装饰器:(参考https://www.cnblogs.com/linhaifeng/articles/6140395.html)

 1 user_list=[
 2     {'name':'alex','passwd':'123'},
 3     {'name':'linhaifeng','passwd':'123'},
 4     {'name':'wupeiqi','passwd':'123'},
 5     {'name':'yuanhao','passwd':'123'},
 6 ]
 7 current_user={'username':None,'login':False}
 8 def auth_deco(func):
 9     def wrapper(*args,**kwargs):
10         if current_user['username'] and current_user['login']:
11             res=func(*args,**kwargs)
12             return res
13         username=input('please input the username: ')
14         password=input('please input the password: ')
15         for user_dic in user_list:
16             if username ==user_dic['name'] and password == user_dic['passwd']:
17                 current_user['username']=username
18                 current_user['login']=True
19                 res=func(*args,**kwargs)
20                 return res
21         else:
22             print('The username or password is wrong, please try again!')
23     return wrapper
24 
25 @auth_deco
26 def index():
27     print('welcome to visit the JD supermarket!')
28 
29 @auth_deco
30 def home(name):
31     print('welcome to the main page!')
32 
33 @auth_deco
34 def shopping_car(name):
35     print('you can check your goods')
36 
37 @auth_deco
38 def order(name):
39     print('you can pay the checklists')
40 
41 print(current_user)
42 index()
43 home('name')
44 shopping_car('name')
45 order('name')
46 # {'login': False, 'username': None}
47 # please input the username: alex
48 # please input the password: 123
49 # welcome to visit the JD supermarket!
50 # welcome to the main page!
51 # you can check your goods
52 # you can pay the checklists
原文地址:https://www.cnblogs.com/dylee/p/10798037.html