python 装饰器

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


目录:

一、基本装饰器

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

三、类装饰器



正文:

一、基本装饰器

        装饰不带参数的函数


  
  
  1. def  clothes( func):
  2.      def  wear():
  3.          print( 'Buy clothes!{}'. format(func.__name__))
  4.          return func()
  5.      return wear
  6. @clothes
  7. def  body():
  8.      print( 'The body feels could!')
  9.     
  10. #备注:@是语法糖
  11. # 不用语法糖的情况下,使用下面语句也能实现装饰作用:把body再加工,再传给body
  12. # body = clothes(body)

        装饰带一个参数的函数


  
  
  1. def  clothes( func):
  2.      def  wear( anything):             # 实际是定义一个anything参数,对应body函数参数
  3.          print( 'Buy clothes!{}'. format(func.__name__))
  4.          return func(anything)       # 执行func函数,并传入调用传入的anything参数
  5.          # wear = func(anything)    # 在这一步,实际上可以看出来,为啥wear必须带参数,因为它就是func(anything)
  6.      return wear
  7.      # 所以clothes的结果是
  8.      # clothes = wear = func(anything)
  9.      # 不用语法糖的情况下就是
  10.      # body = clothes(body)('hands')
  11.      # 进一步证明:print(body.__name__)  显示的是wear函数
  12.     
  13. @clothes
  14. def  body( part):
  15.      print( 'The body feels could!{}'. format(part))
  16.     
  17. body( 'hands')

    装饰带不定长参数的函数

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

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


  
  
  1. def  clothes( func):
  2.      def  wear( *args, **kwargs):
  3.          print( 'Buy clothes!{}'. format(func.__name__))
  4.          return func(*args, **kwargs)
  5.      return wear
  6. @clothes
  7. def  body( part):
  8.      print( 'The body feels could!{}'. format(part))
  9. @clothes
  10. def  head( head_wear, num=2):
  11.      print( 'The head need buy {} {}!'. format(num, head_wear))
  12. body( 'hands')
  13. head( 'headdress')

    装饰器带参数


  
  
  1. # 把装饰器再包装,实现了seasons传递装饰器参数。
  2. def  seasons( season_type):
  3.      def  clothes( func):
  4.          def  wear( *args, **kwargs):
  5.              if season_type ==  1:
  6.                 s =  'spring'
  7.              elif season_type ==  2:
  8.                 s =  'summer'
  9.              elif season_type ==  3:
  10.                 s =  'autumn'
  11.              elif season_type ==  4:
  12.                 s =  'winter'
  13.              else:
  14.                  print( 'The args is error!')
  15.                  return func(*args, **kwargs)
  16.              print( 'The season is {}!{}'. format(s, func.__name__))
  17.              return func(*args, **kwargs)
  18.          return wear
  19.      return clothes
  20. @seasons(2)
  21. def  children():
  22.      print( 'i am children')
  23. children()




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

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

    把装饰器写在类里

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


  
  
  1. class  Buy( object):
  2.      def  __init__( self, func):
  3.         self.func = func
  4.      # 在类里定义一个函数
  5.      def  clothes( func):             # 这里不能用self,因为接收的是body函数
  6.          # 其它都和普通的函数装饰器相同
  7.          def  ware( *args, **kwargs):
  8.              print( 'This is a decrator!')
  9.              return func(*args, **kwargs)
  10.          return ware
  11. @Buy.clothes
  12. def  body( hh):
  13.      print( 'The body feels could!{}'. format(hh))
  14. body( 'hh')

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

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


  
  
  1. class  Buy( object):
  2.      def  __init__( self):
  3.         self.reset =  True         # 定义一个类属性,稍后在装饰器里更改
  4.         self.func =  True         
  5.      # 在类里定义一个装饰器
  6.      def  clothes( func):     # func接收body
  7.          def  ware( self, *args, **kwargs):     # self,接收body里的self,也就是类实例
  8.              print( 'This is a decrator!')
  9.              if self.reset ==  True:         # 判断类属性
  10.                  print( 'Reset is Ture, change Func..')
  11.                 self.func =  False         # 修改类属性
  12.              else:
  13.                  print( 'reset is False.')
  14.              return func(self, *args, **kwargs)
  15.          return ware
  16.     @clothes
  17.      def  body( self):
  18.          print( 'The body feels could!')
  19. b = Buy()     # 实例化类
  20. b.body()      # 运行body
  21. print(b.func)     # 查看更改后的self.func值,是False,说明修改完成

三、类装饰器

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


  
  
  1. class  Decrator( object):
  2.      def  __init__( self, func):                         # 传送的是test方法
  3.         self.func = func
  4.      def  __call__( self, *args, **kwargs):       # 接受任意参数
  5.              print( '函数调用CALL')
  6.              return self.func(*args, **kwargs)     # 适应test的任意参数        
  7. @Decrator                         # 如果带参数,init中的func是此参数。
  8. def  test( hh):
  9.      print( 'this is the test of the function !',hh)
  10. test( 'hh')

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

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

    下面自已做一个property


  
  
  1. class  Decrator( object):
  2.      def  __init__( self, func):
  3.         self.func = func
  4.      def  __get__( self, instance, owner):
  5.          '''
  6.         instance:代表实例,sum中的self
  7.         owner:代表类本身,Test类
  8.         
  9.         '''
  10.          print( '调用的是get函数')
  11.          return self.func(instance)      # instance就是Test类的self
  12. class  Test( object):
  13.      def  __init__( self):
  14.         self.result =  0
  15.     @Decrator
  16.      def  sum( self):
  17.          print( 'There is the Func in the Class !')
  18. t = Test()
  19. print(t. sum)             # 众所周知,属性是不加括号的,sum真的变成了属性

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


  
  
  1. class  Decrator( object):
  2.      def  __init__( self, func):
  3.         self.func = func
  4.      def  __get__( self, instance, owner):
  5.          print( '调用的是get函数')
  6.          return self.func(instance)
  7. class  Test( object):
  8.      def  __init__( self, *args, **kwargs):
  9.         self.value_list = []
  10.          if args:
  11.              for i  in args:
  12.                  if  str(i).isdigit():
  13.                     self.value_list.append(i)
  14.          if kwargs:
  15.              for v  in kwargs.values():
  16.                  if  str(v).isdigit():
  17.                     self.value_list.append(v)
  18.     @Decrator
  19.      def  sum( self):
  20.         result =  0
  21.          print(self.value_list)
  22.          for i  in self.value_list:
  23.             result += i
  24.          return result
  25. t = Test( 1, 2, 3, 4, 5, 6, 7, 8,i= 9,ss= 10,strings =  'lll')
  26. print(t. sum)

    



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值