再学装饰器
装饰器
实现装饰器的知识储备
2.高阶函数
a.把一个函数名当做实参传给另外一个函数(在不修改被装饰函数源代码的情况下为其添加功能)
b.返回值中包含函数名(不修改函数的调用方式)
3.嵌套函数
高阶函数+嵌套函数 ==> 装饰器
1.函数即变量:
图一中x,y,test,calc都是变量,同样图二中的foo和bar函数名也是变量。
2.高阶函数
代码解析:
def bar(): print('in the bar') def test(func): print(func) test(bar) 把bar当做变量传给test函数当做参数,此时print(func)就是bar的地址,func()就是调用bar()函数
下一步思路:
def bar(): time.sleep(3) print('in the bar') def test(func): start_time = time.time() func() # run bar() stop_time = time.time() print('the func run time is %s' % (stop_time - start_time)) test(bar) 不是装饰器,虽然没有修改源代码,但是调用方式变了,本来是bar(),现在是test(bar)
接下来思路:
import time def bar(): time.sleep(3) print('in the bar') def test(func): print(func) return func print(test(bar)) # test(bar)就是传进去bar函数的地址 结果: <function bar at 0x000002142A5A1E18> <function bar at 0x000002142A5A1E18>
import time def bar(): time.sleep(3) print('in the bar') def test(func): print(func) return func bar = test(bar) # 把地址重新赋值给bar变量 bar() # 此时执行bar函数
3.嵌套函数:
引入:局部作用域和全局作用域的访问顺序
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
x = 0 def grandpa(): x = 1 def dad(): x = 2 def son(): x = 3 print(x) son() dad() grandpa()
def foo(): print('in the foo') def bar(): print('in the bar') bar() foo()
4.开始写装饰器
装饰器的原则是:开放对扩展(增加新功能)、封闭修改源代码(不改变源代码)、不改变调用方式(原函数是怎么调用的现在还是怎么调用)。
4.1使用高阶函数尝试给原函数增加功能。
import time def test1(): time.sleep(1) print('in the test1') def test2(): time.sleep(2) print('in the test2') def deco(func): start_time = time.time() return func stop_time = time.time() print('in func run time is %s'%(stop_time-start_time)) test1 = deco(test1) test1() test2 = deco(test2) test2() 利用高阶函数实现了上面的思路,不改变原函数的调用方式,不过没有加功能
4.2利用嵌套函数
def timer(): def deco(): pass
4.3嵌套函数往上面没加功能里面套形成装饰器
import time def test1(): time.sleep(1) print('in the test1') def test2(): time.sleep(2) print('in the test2') def timer(func): # timer(test1) func = test1 def deco(): start_time = time.time() func() # run test1 stop_time = time.time() print('in func run time is %s' % (stop_time - start_time)) return deco test1 = timer(test1) test1() # -->deco test2 = timer(test2) test2()
4.4最终的装饰器(语法糖引入)
import time def timer(func): def deco(): start_time = time.time() func() stop_time = time.time() print('in func run time is %s' % (stop_time - start_time)) return deco @timer def test1(): time.sleep(1) print('in the tset1') @timer def test2(): time.sleep(2) print('in the test2') test1() test2()