zoukankan      html  css  js  c++  java
  • Python进阶-----类的装饰器及应用

    回顾什么是装饰器:
      装饰器定义:本质就是函数(高阶函数),功能是为其他函数(对象)添加新功能

    一、类的装饰器基本实现原理如下:

    1 def deco(cls):
    2     print('类的装饰器=========》')
    3     print('='*20)
    4     return cls
    5 
    6 @deco      #====> Foo = deco(Foo)
    7 class Foo:
    8     pass

    二、上述的简单装饰器是没有参数的,现在我们加上参数

     1 def cls_decorator(**kwargs):            #支持传入参数(属性和对应的值),字典形式
     2     def deco(cls):
     3         for key,val in kwargs.items():
     4             setattr(cls,key,val)        #给类设置对应的属性和值
     5         return cls
     6     return deco
     7 
     8 @cls_decorator(name='Menawey',age=24,gender='male')        # 1 运行cls_decorator(...),返回deco;2 @deco===> Peolple = deco(People)
     9 #相当于给People类设置了name、age、gender属性
    10 class People:
    11     pass
    12 
    13 print(People.__dict__)                                   #查看被装饰过的类的属性字典

       通过这样就可以动态的给不同的类在他实例化前增加属性

    三、结合描述符
      通过描述符和类的装饰器组合使用,可以完成很多功能,比如为类添加属性,并且可以限定属性的类型。

     1 #描述符
     2 class Desc:
     3     def __init__(self,key,value_type):
     4         self.key = key
     5         self.value_type = value_type
     6     def __get__(self, instance, owner):
     7         return instance.__dict__[self.key]
     8     def __set__(self, instance, value):
     9         if not isinstance(value,self.value_type):
    10             raise TypeError('%s 传入的类型不是 %s'%(self.key,self.value_type))
    11         instance.__dict__[self.key] = value
    12     def __delete__(self, instance):
    13         instance.__dict__.pop(self.key)
    14 
    15 #装饰器
    16 def cls_decorator(**kwargs):            #支持传入参数(属性和对应的值),字典形式
    17     def deco(cls):
    18         for key,val in kwargs.items():    #这里需要用到描述符对属性进行代理,但是val是指定的类型,所以要用Desc(key,val)来描述为对应的值
    19             setattr(cls,key,Desc(key,val))        #给类设置对应的属性和值
    20         return cls
    21     return deco
    22 
    23 @cls_decorator(name=str,age=int,gender=str,salary=float)    #使用装饰器
    24 
    25 #被装饰和描述的类
    26 class People:
    27     def __init__(self,name,age,gender,salary):
    28         self.name = name
    29         self.age = age
    30         self.gender = gender
    31         self.salary = salary
    32 
    33 p1 = People('Menawey',24,'male',11.1)  #因为gender属性指定的是sstr,但是TypeError: age 传入的类型不是 <class 'int'>
    34 print(People.__dict__)
  • 相关阅读:
    mysql 从5.1升级到5.5.33 后 innodb 表出错 及 innodb表修复
    (未解决)在JSTL中,session 和 sessionScope 有什么区别 ??
    ubuntu 12.04安装redis2.6.16
    SOA,不看你永远不知道的事
    Failed to retrieve procctx from ht. constr
    CUSPARSE 第三章 CUSPARAE索引和数据格式
    yii框架网址解析问题
    以图搜图相关资料
    JMeter工具的使用-ForEach
    [cocos2d-x]针对不同的设备,选取不同的自适应图片
  • 原文地址:https://www.cnblogs.com/Meanwey/p/9901998.html
Copyright © 2011-2022 走看看