一、实现装饰器的预备知识
装饰器 = 高阶函数 + 寒素嵌套 + 闭包
1、高价函数定义:
1.函数接收的参数是一个函数名
2.函数的返回值是一个函数名
3.满足上述条件任意一个,都可称之为高阶函数
例1:铺垫
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 import time 2 #例1 3 def fn(): 4 print('这是被调用函数') 5 time.sleep(2) 6 7 def test(func): 8 print('高阶函数将要开始运行') 9 start_time = time.time() 10 func() 11 end_time = time.time() 12 print('被调用函数的运行时间%s'%(end_time - start_time)) 13 14 test(fn)
例2
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #例2 2 import time 3 def fn(): 4 print('这是被调用函数') 5 time.sleep(2) 6 def test(func): 7 print('正在执行高阶函数') 8 return func 9 #第一种调用 10 f = test(fn) 11 print(f) 12 f() 13 14 ## 第二种调用,升级版 :将调用函数test(func)的返回值赋值给一个与被调用函数fn()同名的变量fn,最后实现的效果就是 15 #(1)不改变被调用函数fn()的源代码 16 #(2) 不改变被调用函数fn()的调用方式 17 fn = test(fn) 18 print(fn) 19 fn()
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 正在执行高阶函数 2 <function fn at 0x0000017065C999D8> 3 这是被调用函数 4 正在执行高阶函数 5 <function fn at 0x0000017065C999D8> 6 这是被调用函数
升级版 :将调用函数test(func)的返回值赋值给一个与被调用函数fn()同名的变量fn,最后实现的效果就是
(1)不改变被调用函数fn()的源代码
(2) 不改变被调用函数fn()的调用方式
例3 这种情况出现的结果是 多运行了一行
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 # 例3 2 import time 3 def fn(): 4 print('这是被调用函数') 5 time.sleep(2) 6 7 def test(func): 8 print('开始执行调用函数') 9 start_time = time.time() 10 func() 11 end_time = time.time() 12 return func # 这种情况出现的结果是 多运行了一行 13 14 fn = test(fn) 15 fn()
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 开始执行调用函数 2 这是被调用函数 3 这是被调用函数
例4
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #例4 2 def fn(): 3 print('这是被调用函数') 4 def test(func): 5 print('正在执行高阶函数') 6 res = func() 7 print('被调用函数执行完毕') 8 return res 9 10 fn = test(fn) 11 # fn() # 报错 :TypeError: 'NoneType' object is not callable
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 正在执行高阶函数 2 这是被调用函数 3 被调用函数执行完毕
即使赋了一个值,也还是解决不了多打印一行的结果。所以单层函数解决不了这个问题
二、嵌套函数