zoukankan      html  css  js  c++  java
  • 获取类属性的定义顺序,摘抄至PythonCookBook

    # 描述符 + 元类 爽爆天
    
    from collections import OrderedDict
    
    
    # 描述符的基类,通过类属性来指定参数
    class Typed:
        # 赋值类型给子类继承用
        _expected_type = type(None)
    
        def __init__(self, name=None):
            self._name = name
    
        def __set__(self, instance, value):
            if not isinstance(value, self._expected_type):
                raise TypeError('Expected' + str(self._expected_type))
            instance.__dict__[self._name] = value
    
    
    class Integer(Typed):
        _expected_type = int
    
    
    class Float(Typed):
        _expected_type = float
    
    
    class String(Typed):
        _expected_type = str
    
    
    # 前面的都还算常规操作,懂描述符的肯定要想,取值的时候,如何取值
    class OrderedMeta(type):
        def __new__(cls, clsname, bases, clsdict):
            # 这里又到时候返回给__init__的时候一个普通字典
            d = dict(clsdict)
            order = []
            # Orderdict就是用来给这里赋值描述符实例的_name用的
            # 为了后续的方法as_csv输出不要出现顺序问题
            # 所以for循环的时候,用了clsdict这个有序字典,返回的时候又给了普通字典
            # 因为默认的就是普通的字典,你用有序字典也没问题,但还是返回一个普通的不会出现兼容问题
            for name, value in clsdict.items():
                if isinstance(value, Typed):
                    # 这个就更加厉害了,通过描述符的赋值操作,修改描述符实例的属性名,后面直接可以通过属性名取值
                    value._name = name
                    order.append(name)
            # 这个列表就是到时候用来去描述符属性用的,也就是给as_csv用的
            d['_order'] = order
            return super(OrderedMeta, cls).__new__(cls, clsname, bases, d)
    
        @classmethod
        def __perpare__(cls, clsname, bases):
            return OrderedDict()
    
    class Structure(metaclass=OrderedMeta):
        def as_csv(self):
            return ','.join(str(getattr(self,name)) for name in self._order)
    
    
    class Stock(Structure):
        name = String()
        shares = Integer()
        price = Float()
    
        def __init__(self, name, shares, price):
            self.name = name
            self.shares = shares
            self.price = price
    
    
    s = Stock('GOOD', 100, 490.1)
    print(s.name)
    print(s.as_csv())
    

     上面是完整的代码摘抄,确实写的很棒,那是相当的厉害。啥时候等我这么厉害就爽大了。

    OrderedDict的使用,让我也能更加清晰的认识到,为什么要用,需要的时候才用到。

    但类的属性,本来用的是普通的dict,所以书中后面又用dict还原过去,

    上面代码的需求:

    我们想自动记录下属性和方法在类中定义的顺序。这样就能利用这个顺序来完成各种操作(例如序列化处理、将属性映射到数据库中等)

  • 相关阅读:
    京东咚咚架构演讲读后感
    京东峰值系统设计读后感
    游戏服务器的架构演讲读后感
    菜鸟弹性调度系统的架构设计读后感
    阿里如何实现秒级百万TPS?搜索离线大数据平台架构解读读后感
    阿里游戏高可用架构设计实践读后感
    淘宝架构背后——零售业务中台架构设计探讨及实践读后感
    本地存储的时候需要类型转换
    禁止输入框显示用户历史输入历史记录
    项目必备!永无 bug 注释
  • 原文地址:https://www.cnblogs.com/sidianok/p/13728764.html
Copyright © 2011-2022 走看看