Why does Python not support record type? (i.e. mutable namedtuple)

后端 未结 11 1581
眼角桃花
眼角桃花 2020-12-12 22:10

Why does Python not support a record type natively? It\'s a matter of having a mutable version of namedtuple.

I could use namedtuple._replace. But I nee

11条回答
  •  一个人的身影
    2020-12-12 22:31

    Here is a complete mutable namedtuple I made, which behaves like a list and is totally compatible with it.

    class AbstractNamedArray():
        """a mutable collections.namedtuple"""
        def __new__(cls, *args, **kwargs):
            inst = object.__new__(cls)  # to rename the class
            inst._list = len(cls._fields)*[None]
            inst._mapping = {}
            for i, field in enumerate(cls._fields):
                inst._mapping[field] = i
            return inst
    
        def __init__(self, *args, **kwargs):
            if len(kwargs) == 0 and len(args) != 0:
                assert len(args) == len(self._fields), 'bad number of arguments'
                self._list = list(args)
            elif len(args) == 0 and len(kwargs) != 0:
                for field, value in kwargs.items():
                    assert field in self._fields, 'field {} doesn\'t exist'
                    self._list[self._mapping[field]] = value
            else:
                raise ValueError("you can't mix args and kwargs")
    
        def __getattr__(self, x):
            return object.__getattribute__(self, '_list')[object.__getattribute__(self, '_mapping')[x]]
    
        def __setattr__(self, x, y):
            if x in self._fields:
                self._list[self._mapping[x]] = y
            else:
                object.__setattr__(self, x, y)
    
        def __repr__(self):
            fields = []
            for field, value in zip(self._fields, map(self.__getattr__, self._fields)):
                fields.append('{}={}'.format(field, repr(value)))
            return '{}({})'.format(self._name, ', '.join(fields))
    
        def __iter__(self):
            yield from self._list
    
        def __list__(self):
            return self._list[:]
    
        def __len__(self):
            return len(self._fields)
    
        def __getitem__(self, x):
            return self._list[x]
    
        def __setitem__(self, x, y):
            self._list[x] = y
    
        def __contains__(self, x):
            return x in self._list
    
        def reverse(self):
            self._list.reverse()
    
        def copy(self):
            return self._list.copy()
    
    
    def namedarray(name, fields):
        """used to construct a named array (fixed-length list with named fields)"""
        return type(name, (AbstractNamedarray,), {'_name': name, '_fields': fields})
    

提交回复
热议问题