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还原过去,

    上面代码的需求:

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

  • 相关阅读:
    刷题[极客大挑战 2019]HardSQL
    刷题[安洵杯 2019]不是文件上传
    归并排序算法及其JS实现
    快速排序算法原理及其js实现
    圣杯布局
    什么是文档流
    AngularJs四大特性
    call,apply,bind的区别
    计算给定数组 arr 中所有元素的总和的几种方法
    es6之Decorator
  • 原文地址:https://www.cnblogs.com/sidianok/p/13728764.html
Copyright © 2011-2022 走看看