一、python装饰器基本概念
定义:本质是函数,用来装饰其他函数,即为其他函数添加附加功能。
原则:1.不能修改被装饰函数的源代码;
2.不能修改被装饰函数的调用方式。
实现装饰器的知识储备:
1.函数即“变量”。
2.高阶函数
a.把一个 函数名 当作实参传给另一个函数;
b.返回值中包含 函数名 。
3.嵌套函数
即在用def定义一个函数的函数体中再用def定义函数。
高阶函数 + 嵌套函数 => 装饰器
二、函数即“变量”
定义一个变量
1 x = 1
变量名x相当于一个门牌号,而1就是这个门牌号所指房间中的内容。
定义一个函数
1 def foo(): 2 print(‘in the foo‘)
函数名foo就相当于一个门牌号,而函数体 print(‘in the foo‘) 作为一串字符串存在这个门牌号所指的房间中。
故 函数即“变量”
三、高阶函数
a. 把一个函数名当作实参传递给另一个函数(在不修改被装饰函数源代码的情况下为其添加功能);
b. 返回值中包含函数名(不改变函数的调用方式)。
代码示例:
1 #a:把一个 函数名 当作实参传给另一个函数 (在不修改被装饰函数源代码的情况下为其添加功能) 2 import time 3 4 def bar(): 5 time.sleep(3) 6 print(‘in the bar‘) 7 8 def test1(func): 9 print(func) 10 start_time = time.time() 11 func() #运行bar() 12 stop_time = time.time() 13 print("the func run time is %s"%(stop_time-start_time)) 14 15 test1(bar) # bar即为函数的内存地址,加“()”即为调用此函数 16 #bar()
<function bar at 0x0000021F3E956048> in the bar the func run time is 3.0008294582366943
1 #b:返回值中包含 函数名 (不改变函数的调用方式) 2 import time 3 4 def bar(): 5 time.sleep(3) 6 print(‘in the bar‘) 7 8 def test2(func): 9 print(func) 10 return func 11 12 t = test2(bar) 13 print(t) 14 bar = test2(bar) # 注意这一句 15 bar() 16 t() #run bar
<function bar at 0x00000265D5486048> <function bar at 0x00000265D5486048> <function bar at 0x00000265D5486048> in the bar in the bar
四、嵌套函数
在用def定义一个函数的函数体中再用def定义函数。
代码示例:
1 def foo(): 2 print("in the foo") 3 def bar(): 4 print("in the bar") 5 bar() 6 #bar() #错误写法 ,函数即变量,可把bar看作局部变量 7 foo()
in the foo in the bar
五、装饰器
1. 引例,为test1()增加输出运行时间的功能。
1 import time 2 3 def timer(func): #timmer(test1) func=test1 4 def deco(): 5 start_time = time.time() 6 func() #在def中,func()只是一串字符串,func()并没有调用执行 7 stop_time = time.time() 8 print("the func run time is %s" % (stop_time - start_time)) 9 return deco 10 11 def test1(): 12 time.sleep(3) 13 print("in the test1") 14 15 test1 = timer(test1) #注意这一句 16 test1() #运行test()即为运行deco()
in the test1 the func run time is 3.0002777576446533
2.无参数装饰器
import time def timer(func): #timmer(test1) func=test1 def deco(): start_time = time.time() func() #在def中,func()只是一串字符串,func()并没有调用执行 stop_time = time.time() print("the func run time is %s" % (stop_time - start_time)) return deco @timer # test1=timer(test1) def test1(): time.sleep(3) print("in the test1") test1()
in the test1 the func run time is 3.0149574279785156
引入 @timer ,即相当于 test1=timer(test1) 语句。
3.带不确定个数个参数的装饰器
1 import time 2 3 def timer(func): #timmer(test1) func=test1 4 def deco(*args,**kwargs): 5 start_time = time.time() 6 func(*args,**kwargs) #在def中,func()只是一串字符串,func()并没有调用执行 7 stop_time = time.time() 8 print("the func run time is %s" % (stop_time - start_time)) 9 return deco 10 11 @timer # test1=timer(test1) 12 def test1(): 13 time.sleep(3) 14 print("in the test1") 15 16 @timer 17 def test2(name): 18 time.sleep(1) 19 print("in the test2",name) 20 21 test1() 22 test2(‘ztian‘)
in the test1 the func run time is 3.000495195388794 in the test2 ztian the func run time is 1.000511884689331
利用*args和**kwargs实现不定参数个数的装饰器。