返回
顶部

修改密码

首页 > 文章 > 财经 > 正文
九步就可入门Python装饰器

+1

-1

收藏

+1

-1

点赞0

评论0

标题:九步就可入门Python装饰器
详情介绍-作者:xiaowei-来源: 极全网 -如有问题点击:在线客服帮助


第一步:最简单的函数,准备附加额外功能

#-*-coding:gbk-*-'''示例1:最简单的函数,表示调用了两次'''defmyfunc():print("myfunc()called.")myfunc()myfunc()

第二步:使用装饰函数在函数执行前和执行后分别附加额外功能

#-*-coding:gbk-*-'''示例2:替换函数(装饰)装饰函数的参数是被装饰的函数对象,返回原函数对象装饰的实质语句:myfunc=deco(myfunc)'''defdeco(func):print("beforemyfunc()called.")func()print("aftermyfunc()called.")returnfuncdefmyfunc():print("myfunc()called.")myfunc=deco(myfunc)myfunc()myfunc()

第三步:使用语法糖@来装饰函数

#-*-coding:gbk-*-'''示例3:使用语法糖@来装饰函数,相当于“myfunc=deco(myfunc)”但发现新函数只在第一次被调用,且原函数多调用了一次'''defdeco(func):print("beforemyfunc()called.")func()print("aftermyfunc()called.")returnfunc@decodefmyfunc():print("myfunc()called.")myfunc()myfunc()

相关推荐:《Python视频教程》

第四步:使用内嵌包装函数来确保每次新函数都被调用

#-*-coding:gbk-*-'''示例4:使用内嵌包装函数来确保每次新函数都被调用,内嵌包装函数的形参和返回值与原函数相同,装饰函数返回内嵌包装函数对象'''defdeco(func):def_deco():print("beforemyfunc()called.")func()print("aftermyfunc()called.")#不需要返回func,实际上应返回原函数的返回值return_deco@decodefmyfunc():print("myfunc()called.")return'ok'myfunc()myfunc()

第五步:对带参数的函数进行装饰

#-*-coding:gbk-*-'''示例5:对带参数的函数进行装饰,内嵌包装函数的形参和返回值与原函数相同,装饰函数返回内嵌包装函数对象'''defdeco(func):def_deco(a,b):print("beforemyfunc()called.")ret=func(a,b)print("aftermyfunc()called.result:%s"%ret)returnretreturn_deco@decodefmyfunc(a,b):print("myfunc(%s,%s)called."%(a,b))returna+bmyfunc(1,2)myfunc(3,4)

第六步:对参数数量不确定的函数进行装饰

#-*-coding:gbk-*-'''示例6:对参数数量不确定的函数进行装饰,参数用(*args,**kwargs),自动适应变参和命名参数'''defdeco(func):def_deco(*args,**kwargs):print("before%scalled."%func.__name__)ret=func(*args,**kwargs)print("after%scalled.result:%s"%(func.__name__,ret))returnretreturn_deco@decodefmyfunc(a,b):print("myfunc(%s,%s)called."%(a,b))returna+b@decodefmyfunc2(a,b,c):print("myfunc2(%s,%s,%s)called."%(a,b,c))returna+b+cmyfunc(1,2)myfunc(3,4)myfunc2(1,2,3)myfunc2(3,4,5)

第七步:让装饰器带参数

#-*-coding:gbk-*-'''示例7:在示例4的基础上,让装饰器带参数,和上一示例相比在外层多了一层包装。装饰函数名实际上应更有意义些'''defdeco(arg):def_deco(func):def__deco():print("before%scalled[%s]."%(func.__name__,arg))func()print("after%scalled[%s]."%(func.__name__,arg))return__decoreturn_deco@deco("mymodule")defmyfunc():print("myfunc()called.")@deco("module2")defmyfunc2():print("myfunc2()called.")myfunc()myfunc2()

第八步:让装饰器带类参数

#-*-coding:gbk-*-'''示例8:装饰器带类参数'''classlocker:def__init__(self):print("locker.__init__()shouldbenotcalled.")@staticmethoddefacquire():print("locker.acquire()called.(这是静态方法)")@staticmethoddefrelease():print("locker.release()called.(不需要对象实例)")defdeco(cls):'''cls必须实现acquire和release静态方法'''def_deco(func):def__deco():print("before%scalled[%s]."%(func.__name__,cls))cls.acquire()try:returnfunc()finally:cls.release()return__decoreturn_deco@deco(locker)defmyfunc():print("myfunc()called.")myfunc()myfunc()

第九步:装饰器带类参数,并分拆公共类到其他py文件中,同时演示了对一个函数应用多个装饰器。

#-*-coding:gbk-*-'''mylocker.py:公共类for示例9.py'''classmylocker:def__init__(self):print("mylocker.__init__()called.")@staticmethoddefacquire():print("mylocker.acquire()called.")@staticmethoddefunlock():print("mylocker.unlock()called.")classlockerex(mylocker):@staticmethoddefacquire():print("lockerex.acquire()called.")@staticmethoddefunlock():print("lockerex.unlock()called.")deflockhelper(cls):'''cls必须实现acquire和release静态方法'''def_deco(func):def__deco(*args,**kwargs):print("before%scalled."%func.__name__)cls.acquire()try:returnfunc(*args,**kwargs)finally:cls.unlock()return__decoreturn_deco
#-*-coding:gbk-*-'''示例9:装饰器带类参数,并分拆公共类到其他py文件中同时演示了对一个函数应用多个装饰器'''frommylockerimport*classexample:@lockhelper(mylocker)defmyfunc(self):print("myfunc()called.")@lockhelper(mylocker)@lockhelper(lockerex)defmyfunc2(self,a,b):print("myfunc2()called.")returna+bif__name__=="__main__":a=example()a.myfunc()print(a.myfunc())print(a.myfunc2(1,2))print(a.myfunc2(3,4))

相关推荐:

版权声明:本文内容由极全网实名注册用户自发贡献,版权归原作者所有,极全网-官网不拥有其著作权,亦不承担相应法律责任。具体规则请查看《极全网用户服务协议》和《极全网知识产权保护指引》。如果您发现极全网中有涉嫌抄袭的内容,点击进入填写侵权投诉表单进行举报,一经查实,极全网将立刻删除涉嫌侵权内容。

扫一扫在手机打开

评论
已有0条评论
0/150
提交
热门评论
相关推荐
换一批
热点排行