一、什么是装饰器

  装饰器本质就是函数,功能是为其他函数附加功能

 

二、装饰器遵循的原则

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

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

 

三、实现装饰器的知识储备

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

 

示例1: 用函数实现

 1 #计算从1-100,统计函数运行时间
 2 
 3 import time
 4 def cal(l):
 5     start_time=time.time()
 6     res=0
 7     for i in l:
 8         time.sleep(0.1)
 9         res+=i
10     stop_time = time.time()
11     print('函数的运行时间是%s' %(stop_time-start_time))
12     return res
13 
14 print(cal(range(100)))   #直接打印得到运行的时间

执行结果:

1 函数的运行时间是10.007169723510742
2 4950

 

示例2:用装饰器实现函数运行时间

 1 import time
 2 def timmer(func):
 3     def wrapper(*args,**kwargs):
 4         start_time=time.time()
 5         res=func(*args,**kwargs)
 6         stop_time = time.time()
 7         print('函数运行时间是%s' %(stop_time-start_time))
 8         return res
 9     return wrapper
10 
11 @timmer   #调用装饰器
12 def cal(l):
13     res=0
14     for i in l:
15         time.sleep(0.1)
16         res+=i
17     return res
18 
19 res=cal(range(20))
20 print(res)

 

四、高阶函数高阶函数定义

1.函数接收的参数是一个函数名

2.函数的返回值是一个函数名

3.满足上述条件任意一个,都可称之为高阶函数

 

高阶函数示例如下:

示例1:函数接收的参数是一个函数名

 1 #1.函数接收的参数是一个函数名
 2 import time
 3 def foo():
 4     time.sleep(3)
 5     print('你好啊林师傅')
 6 
 7 def test(func):    #test高阶函数
 8     # print(func)  #获取到内存地址
 9     start_time=time.time()
10     func()
11     stop_time = time.time()
12     print('函数运行时间是  %s' % (stop_time-start_time))
13 # foo()
14 test(foo)

执行结果:

1 你好啊林师傅
2 函数运行时间是  3.0003013610839844
3 来自foo

 

示例2

 1 def foo():
 2     print('from the foo')
 3 def test(func):
 4     return func
 5 
 6 # res=test(foo)
 7 # # print(res)
 8 # res()
 9 
10 foo=test(foo)
11 # # print(res)
12 foo()
13 
14 import time
15 def foo():
16     time.sleep(3)
17     print('来自foo')
18 
19 #不修改foo源代码
20 #不修改foo调用方式

 

示例3:

 1 #多运行了一次,不合格
 2 import time
 3 def foo():
 4     time.sleep(3)
 5     print('来自foo')
 6 
 7 def timer(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 foo()

 

示例4:

 1 #没有修改被修饰函数的源代码,也没有修改被修饰函数的调用方式,但是也没有为被修饰函数添加新功能
 2 import time
 3 def foo():
 4     time.sleep(3)
 5     print('来自foo')
 6 
 7 def timer(func):
 8     start_time=time.time()
 9     return func
10     stop_time = time.time()
11     print('函数运行时间是  %s' % (stop_time-start_time))
12 
13 foo=timer(foo)
14 foo()

执行结果:

1 来自foo

结论:高阶函数,满足不了装饰器的功能。

 

高阶函数总结:

1.函数接收的参数是一个函数名
  作用:在不修改函数源代码的前提下,为函数添加新功能,
  不足:会改变函数的调用方式

2.函数的返回值是一个函数名
  作用:不修改函数的调用方式
  不足:不能添加新功能

 

五、函数的嵌套

1、什么是函数的嵌套?

    通过在函数内部def的关键字再声明一个函数即为嵌套

 

示例:

1 def father(name):
2     def son():
3         print('我的爸爸是%s' %name)
4         def grandson():
5             name='就是我自己'
6             print('我的爷爷是%s' %name)
7         grandson()
8     son()
9 father('linhaifeng')

执行结果:

1 我的爸爸是linhaifeng
2 
3 我的爷爷是就是我自己

 

六、闭包

 1 #闭包:在一个作用域里放入定义变量,相当于打了一个包
 2 def father(auth_type):
 3     # print('from father %s' %name)
 4     def son():
 5         # name='linhaifeng_1'
 6         # print('我的爸爸是%s' %name)
 7         def grandson():
 8             print('我的爷爷是%s' %auth_type)
 9         grandson()
10     # print(locals())
11     son()
12 # father('linhaifeng')
13 father('filedb')

执行结果:

1 我的爷爷是filedb

 

七、无参装饰器

无参装饰器=高级函数+函数嵌套

 

1、基本框架

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

 

2、基本装饰器(基本框架+参数+功能+返回值+使用装饰器+语法糖@)

import time

def timmer(func): #func=test
    def wrapper():
        # print(func)
        start_time=time.time()
        func() #就是在运行test()
        stop_time = time.time()
        print('运行时间是%s' %(stop_time-start_time))
    return wrapper

@timmer #test=timmer(test)  #在函数名前面加个@ ,这就是语法糖
def test():
    time.sleep(3)
    print('test函数运行完毕')

test()

代码说明:

1 # res=timmer(test)  #返回的是wrapper的地址
2 # res()  #执行的是wrapper()
3 #
4 # test=timmer(test)  #返回的是wrapper的地址
5 # test()  #执行的是wrapper()
6 #
7 #  @timmer  就相当于 test=timmer(test)
View Code

相关文章:

  • 2022-12-23
  • 2021-07-09
  • 2021-09-05
  • 2021-08-02
  • 2021-05-25
  • 2021-10-27
  • 2022-12-23
猜你喜欢
  • 2021-11-16
  • 2021-06-02
  • 2021-07-02
  • 2022-01-07
  • 2022-12-23
相关资源
相似解决方案