python 装饰器有哪些_python之装饰器

一,什么是装饰器?

装饰器本质上就是一个python函数,他可以让其他函数在不需要做任何代码变动的前提下,增加额外的功能,装饰器的返回值也是一个函数对象。

装饰器的应用场景:比如插入日志,性能测试,事务处理,缓存等等场景。

二,装饰器的形成过程。

现在我有一个需求,我想让你测试这个函数的执行时间,在不改变这个函数代码的情况下:

ContractedBlock.gif

ExpandedBlockStart.gif

importtimedeffunc1():print('in func1')deftimer(func):definner():

start=time.time()

func()print(time.time() -start)returninner

func1=timer(func1)

func1()

装饰器---简单版

但是如果有多个函数,我都想让你测试他们的执行时间,你每次是不是都得func1 = timer(func1)?这样还是有点麻烦,因为这些函数的函数名可能是不相同,有func1,func2,graph,等等,所以更简单的方法,python给你提供了,那就是语法糖。

ContractedBlock.gif

ExpandedBlockStart.gif

importtimedeftimer(func):definner():

start=time.time()

func()print(time.time() -start)returninner

@timer#==> func1 = timer(func1)

deffunc1():print('in func1')

func1()

装饰器---语法糖

刚刚我们讨论的装饰器都是装饰不带参数的函数,现在要装饰一个带参数的函数怎么办呢?

ContractedBlock.gif

ExpandedBlockStart.gif

deftimer(func):definner(a):

start=time.time()

func(a)print(time.time() -start)returninner

@timerdeffunc1(a):print(a)

func1(1)

装饰器——带参数的装饰器

装饰器---带参数的装饰器

ContractedBlock.gif

ExpandedBlockStart.gif

importtimedeftimer(func):def inner(*args,**kwargs):

start=time.time()

re= func(*args,**kwargs)print(time.time() -start)returnrereturninner

@timer#==> func1 = timer(func1)

deffunc1(a,b):print('in func1')

@timer#==> func2 = timer(func2)

deffunc2(a):print('in func2 and get a:%s'%(a))return 'fun2 over'func1('aaaaaa','bbbbbb')print(func2('aaaaaa'))

装饰器---hold住所有参数的装饰器

上面的装饰器已经非常完美了,但是有我们正常情况下查看函数信息的方法在此处都会失效:

defindex():'''这是一个主页信息'''

print('from index')print(index.__doc__) #查看函数注释的方法

print(index.__name__) #查看函数名的方法

如何解决呢?

from functools importwrapsdefdeco(func):

@wraps(func)#加在最内层函数正上方

def wrapper(*args,**kwargs):return func(*args,**kwargs)returnwrapper

@decodefindex():'''哈哈哈哈'''

print('from index')print(index.__doc__)print(index.__name__)

三,开放封闭原则。

1.对扩展是开放的

为什么要对扩展开放呢?

我们说,任何一个程序,不可能在设计之初就已经想好了所有的功能并且未来不做任何更新和修改。所以我们必须允许代码扩展、添加新功能。

2.对修改是封闭的

为什么要对修改封闭呢?

就像我们刚刚提到的,因为我们写的一个函数,很有可能已经交付给其他人使用了,如果这个时候我们对其进行了修改,很有可能影响其他已经在使用该函数的用户。

装饰器完美的遵循了这个开放封闭原则。

四,装饰器的主要功能和固定结构。

ContractedBlock.gif

ExpandedBlockStart.gif

deftimer(func):def inner(*args,**kwargs):'''执行函数之前要做的'''re= func(*args,**kwargs)'''执行函数之后要做的'''

returnrereturn inner

装饰器的固定格式

ContractedBlock.gif

ExpandedBlockStart.gif

from functools importwrapsdefdeco(func):

@wraps(func)#加在最内层函数正上方

def wrapper(*args,**kwargs):return func(*args,**kwargs)return wrapper

装饰器的固定格式--wraps版

五,带参数的装饰器。

假如你有成千上万个函数使用了一个装饰器,现在你想把这些装饰器都取消掉,你要怎么做?

一个一个的取消掉? 没日没夜忙活3天。。。

过两天你领导想通了,再让你加上。。。

ContractedBlock.gif

ExpandedBlockStart.gif

defouter(flag):deftimer(func):def inner(*args,**kwargs):ifflag:print('''执行函数之前要做的''')

re= func(*args,**kwargs)ifflag:print('''执行函数之后要做的''')returnrereturninnerreturntimer

@outer(False)deffunc():print(111)

func()

带参数的装饰器

六,多个装饰器装饰一个函数。

ContractedBlock.gif

ExpandedBlockStart.gif

defwrapper1(func):definner():print('wrapper1 ,before func')

func()print('wrapper1 ,after func')returninnerdefwrapper2(func):definner():print('wrapper2 ,before func')

func()print('wrapper2 ,after func')returninner

@wrapper2

@wrapper1deff():print('in f')

f()

多个装饰器装饰一个函数


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部