本文重点:解决了类里面定义的装饰器,在同一个类里面使用的问题,并实现了装饰器的类属性参数传递


目录:

一、基本装饰器

二、在类里定义装饰器,装饰本类内函数

三、类装饰器



正文:

一、基本装饰器

装饰不带参数的函数

defclothes(func):defwear():print('Buyclothes!{}'.format(func.__name__))returnfunc()returnwear@clothesdefbody():print('Thebodyfeelscould!')#备注:@是语法糖#不用语法糖的情况下,使用下面语句也能实现装饰作用:把body再加工,再传给body#body=clothes(body)

装饰带一个参数的函数

defclothes(func):defwear(anything):#实际是定义一个anything参数,对应body函数参数print('Buyclothes!{}'.format(func.__name__))returnfunc(anything)#执行func函数,并传入调用传入的anything参数#wear=func(anything)#在这一步,实际上可以看出来,为啥wear必须带参数,因为它就是func(anything)returnwear#所以clothes的结果是#clothes=wear=func(anything)#不用语法糖的情况下就是#body=clothes(body)('hands')#进一步证明:print(body.__name__)显示的是wear函数@clothesdefbody(part):print('Thebodyfeelscould!{}'.format(part))body('hands')

装饰带不定长参数的函数

通常装饰器不只装饰一个函数,每个函数参数的个数也不相同

这个时候使用不定长参数*args,**kwargs

defclothes(func):defwear(*args,**kwargs):print('Buyclothes!{}'.format(func.__name__))returnfunc(*args,**kwargs)returnwear@clothesdefbody(part):print('Thebodyfeelscould!{}'.format(part))@clothesdefhead(head_wear,num=2):print('Theheadneedbuy{}{}!'.format(num,head_wear))body('hands')head('headdress')

装饰器带参数

#把装饰器再包装,实现了seasons传递装饰器参数。defseasons(season_type):defclothes(func):defwear(*args,**kwargs):ifseason_type==1:s='spring'elifseason_type==2:s='summer'elifseason_type==3:s='autumn'elifseason_type==4:s='winter'else:print('Theargsiserror!')returnfunc(*args,**kwargs)print('Theseasonis{}!{}'.format(s,func.__name__))returnfunc(*args,**kwargs)returnwearreturnclothes@seasons(2)defchildren():print('iamchildren')children()




二、在类里定义装饰器,装饰本类内函数:

类装饰器,装饰函数和类函数调用不同的类函数

把装饰器写在类里

在类里面定义个函数,用来装饰其它函数,严格意义上说不属于类装饰器。

classBuy(object):def__init__(self,func):self.func=func#在类里定义一个函数defclothes(func):#这里不能用self,因为接收的是body函数#其它都和普通的函数装饰器相同defware(*args,**kwargs):print('Thisisadecrator!')returnfunc(*args,**kwargs)returnware@Buy.clothesdefbody(hh):print('Thebodyfeelscould!{}'.format(hh))body('hh')

装饰器装饰同一个类里的函数

背景:想要通过装饰器修改类里的self属性值。

classBuy(object):def__init__(self):self.reset=True#定义一个类属性,稍后在装饰器里更改self.func=True#在类里定义一个装饰器defclothes(func):#func接收bodydefware(self,*args,**kwargs):#self,接收body里的self,也就是类实例print('Thisisadecrator!')ifself.reset==True:#判断类属性print('ResetisTure,changeFunc..')self.func=False#修改类属性else:print('resetisFalse.')returnfunc(self,*args,**kwargs)returnware@clothesdefbody(self):print('Thebodyfeelscould!')b=Buy()#实例化类b.body()#运行bodyprint(b.func)#查看更改后的self.func值,是False,说明修改完成

三、类装饰器

定义一个类装饰器,装饰函数,默认调用__call__方法

#classDecrator(object):def__init__(self,func):#传送的是test方法self.func=funcdef__call__(self,*args,**kwargs):#接受任意参数print('函数调用CALL')returnself.func(*args,**kwargs)#适应test的任意参数@Decrator#如果带参数,init中的func是此参数。deftest(hh):print('thisisthetestofthefunction!',hh)test('hh')

定义一个类装饰器,装饰类中的函数,默认调用__get__方法

实际上把类方法变成属性了,还记得类属性装饰器吧,@property

下面自已做一个property

classDecrator(object):def__init__(self,func):self.func=funcdef__get__(self,instance,owner):'''instance:代表实例,sum中的selfowner:代表类本身,Test类'''print('调用的是get函数')returnself.func(instance)#instance就是Test类的selfclassTest(object):def__init__(self):self.result=0@Decratordefsum(self):print('ThereistheFuncintheClass!')t=Test()print(t.sum)#众所周知,属性是不加括号的,sum真的变成了属性

做一个求和属性sum,统计所有输入的数字的和

classDecrator(object):def__init__(self,func):self.func=funcdef__get__(self,instance,owner):print('调用的是get函数')returnself.func(instance)classTest(object):def__init__(self,*args,**kwargs):self.value_list=[]ifargs:foriinargs:ifstr(i).isdigit():self.value_list.append(i)ifkwargs:forvinkwargs.values():ifstr(v).isdigit():self.value_list.append(v)@Decratordefsum(self):result=0print(self.value_list)foriinself.value_list:result+=ireturnresultt=Test(1,2,3,4,5,6,7,8,i=9,ss=10,strings='lll')print(t.sum)