【python】python装饰器
为什么会用到装饰器?
功能与业务解耦+代码维护便利性
场景:统计函数执时间
import time def cumulation(): t1 = time.time() for i in range(0,10000): print(i * i) t2 = time.time() print('Total Exec Time is {:.4}s'.format(t2 - t1))
如果有很多类似的函数需要计时,则需要每个函数里都加入同样的代码,冗杂、代码不清晰明了。
此时可以用到装饰器!
装饰器 --- 高阶函数+嵌套定义(原则:函数即变量)
def display_time(func): def wrapper(): t1 = time.time() func() t2 = time.time() print('Total Exec Time {:.4}s'.format(t2 - t1)) return t2-t1 return wrapper #语法糖 @display_time def cumulation(): for i in range(0,10000): print(i*i) cumulation()
----------------------------------被修饰函数有返回值-----------------------------------
import time def display_time(func): def wrapper(): t1 = time.time() result = func() t2 = time.time() print('Total Exec Time {:.4}s'.format(t2-t1)) return result return wrapper #语法糖 @display_time def cumulation(): for i in range(0,10000): print(i*i) return i a = cumulation()
----------------------------------被修饰函数带参-----------------------------------------
import time def display_time(func): def wrapper(*args,**kwargs): t1 = time.time() result = func(*args,**kwargs) t2 = time.time() print('Total Exec Time {:.4}s'.format(t2-t1)) return result return wrapper #语法糖 @display_time def cumulation(maxnum): for i in range(0,maxnum): print(i*i) return i a = cumulation(10000)
----------------------------------装饰器带参-----------------------------------------------
import time def log(text): def display_time(func): def wrapper(*args,**kwargs): t1 = time.time() result = func(*args,**kwargs) t2 = time.time() print('Total Exec Time {:.4}s'.format(t2-t1)) print(text) return wrapper return display_time #语法糖 @log('excute') def cumulation(maxnum): for i in range(0,maxnum): print(i*i) cumulation(10000)
------------------------------YouTube解释:清晰明了----------------------------------
def smart_div(func): def inner(a, b): if a > b: a, b = b, a return func(a,b) return inner def div(a,b): print(a/b) div = smart_div(div) div(2,4)
---------------------------------------多个装饰器------------------------------------------
注意:装饰器只对函数进行装饰,装饰器不对装饰器进行装饰!!
装饰器顺序:
def out_1(func): print('i am out_1') def inner_1(): print('i am inner_1') return func() return inner_1 def out_2(func): print('i am out_2') def inner_2(): print('i am inner_2') return func() return inner_2 @out_1 @out_2 def func_print(): print('i am func_print') func_print()
输出结果如下:
i am out_2
i am out_1
i am inner_1
i am inner_2
i am func_print
一句话这么理解:装饰器,只对函数进行装饰,装饰器不对装饰器进行装饰,所以
1~~~~out2先装饰func_print函数,相当于执行func_print = out_2(func_print),所以先打印了 i am out_2,
2~~~~@out_2装饰完之后,@out1再对func_print进行装饰,并且此时的func_print已经指向了inner_2函数,所以@out_1对他进行装饰相当于func_print= out1(inner_2)这个时候就会执行"i am out_1"的打印,
3~~~~此时的func_print就指向了inner_1,就是两个装饰都装饰完毕了,最后一行代码调用了func_print(),所以就相当于调用了inner_1,这个时候打印"i am inner_1"
4~~~~打印完成之后执行到inner_1里的return func() 此时的func是inner_2,再执行inner_2打印‘I am inner_2’,
5~~~~而inner_2里还有return fun(),这时的func才是最初的func_print,最后打印‘i am func_print’
以上描述看似复杂,但是你如果能理解这个黑体加粗的话,装饰器装饰顺序就是so easy!!!!!有木有
扩展:装饰器类型
python装饰器的4种类型:
函数装饰函数、函数装饰类、类装饰函数、类装饰类
1、函数装饰函数
以上介绍的均为函数装饰函数,此处省略。
2、函数装饰类
3、类装饰函数

浙公网安备 33010602011771号