开发者社区> 问答> 正文

简化数据结构的初始化

你写了很多仅仅用作数据结构的类,不想写太多烦人的 init() 函数

展开
收起
哦哦喔 2020-04-17 15:04:56 782 0
1 条回答
写回答
取消 提交回答
  • 可以在一个基类中写一个公用的 __init__() 函数:
    
    import math
    
    class Structure1:
        # Class variable that specifies expected fields
        _fields = []
    
        def __init__(self, *args):
            if len(args) != len(self._fields):
                raise TypeError('Expected {} arguments'.format(len(self._fields)))
            # Set the arguments
            for name, value in zip(self._fields, args):
                setattr(self, name, value)
    然后使你的类继承自这个基类:
    
    # Example class definitions
    class Stock(Structure1):
        _fields = ['name', 'shares', 'price']
    
    class Point(Structure1):
        _fields = ['x', 'y']
    
    class Circle(Structure1):
        _fields = ['radius']
    
        def area(self):
            return math.pi * self.radius ** 2
    使用这些类的示例:
    
    >>> s = Stock('ACME', 50, 91.1)
    >>> p = Point(2, 3)
    >>> c = Circle(4.5)
    >>> s2 = Stock('ACME', 50)
    Traceback (most recent call last):
        File "<stdin>", line 1, in <module>
        File "structure.py", line 6, in __init__
            raise TypeError('Expected {} arguments'.format(len(self._fields)))
    TypeError: Expected 3 arguments
    如果还想支持关键字参数,可以将关键字参数设置为实例属性:
    
    class Structure2:
        _fields = []
    
        def __init__(self, *args, **kwargs):
            if len(args) > len(self._fields):
                raise TypeError('Expected {} arguments'.format(len(self._fields)))
    
            # Set all of the positional arguments
            for name, value in zip(self._fields, args):
                setattr(self, name, value)
    
            # Set the remaining keyword arguments
            for name in self._fields[len(args):]:
                setattr(self, name, kwargs.pop(name))
    
            # Check for any remaining unknown arguments
            if kwargs:
                raise TypeError('Invalid argument(s): {}'.format(','.join(kwargs)))
    # Example use
    if __name__ == '__main__':
        class Stock(Structure2):
            _fields = ['name', 'shares', 'price']
    
        s1 = Stock('ACME', 50, 91.1)
        s2 = Stock('ACME', 50, price=91.1)
        s3 = Stock('ACME', shares=50, price=91.1)
        # s3 = Stock('ACME', shares=50, price=91.1, aa=1)
    你还能将不在 _fields 中的名称加入到属性中去:
    
    class Structure3:
        # Class variable that specifies expected fields
        _fields = []
    
        def __init__(self, *args, **kwargs):
            if len(args) != len(self._fields):
                raise TypeError('Expected {} arguments'.format(len(self._fields)))
    
            # Set the arguments
            for name, value in zip(self._fields, args):
                setattr(self, name, value)
    
            # Set the additional arguments (if any)
            extra_args = kwargs.keys() - self._fields
            for name in extra_args:
                setattr(self, name, kwargs.pop(name))
    
            if kwargs:
                raise TypeError('Duplicate values for {}'.format(','.join(kwargs)))
    
    # Example use
    if __name__ == '__main__':
        class Stock(Structure3):
            _fields = ['name', 'shares', 'price']
    
        s1 = Stock('ACME', 50, 91.1)
        s2 = Stock('ACME', 50, 91.1, date='8/2/2012')
    
    2020-04-17 15:05:04
    赞同 展开评论 打赏
问答标签:
问答地址:
问答排行榜
最热
最新

相关电子书

更多
如何使用Tair增强数据结构构建丰富在线实时场景 立即下载
Apache Flink 流式应用中状态的数据结构定义升级 立即下载
低代码开发师(初级)实战教程 立即下载