Pythonic子类化列表的方式

时间:2018-05-22 14:45:06

标签: python data-structures subclass

这是我的一般问题空间:

我有一个通过I2C设备的字节/位协议。

我有一个命令的“数据库”,可以完整地描述所有位域类型,值和枚举。

我有一个使用数据库的类和一个i2c驱动程序/交易器,这样我就可以调用命令并获得响应。

MyProtocol = Protocol('database.xml',I2CDriver())
theStatus = MyProtocol.GET_STATUS()

为GET_STATUS命令创建正确的字节流,通过i2c发送它并将响应作为字节数组返回。我可以让它在GET_STATUS()实现中打印响应,但我想将该行为移动到返回对象,而不是在命令中。

我希望我的返回对象是“聪明的”:theStatus需要包含字节列表/数组以及对其字段定义的引用。

我希望theStatus像列表/ bytearray一样,所以我可以直接检查字节。我不关心切片是否只是字节列表或bytearray。一旦它们被切掉,它们只是字节。

我希望'theStatus'能够打印print(theStatus),并且可以打印状态中的所有字段。一旦我确定了一个允许我访问字节和数据库的可行数据结构,我对如何实现这一点感到很自在。

我想通过theStatustheStatus.FIELDNAME之类的字段来检查theStatus['FIELDNAME']'。同样的事情:一旦我有一个可行的数据结构,其中包含字节数组和数据库作为成员,我可以实现这一点。

问题是我不知道“正确”的数据结构导致最少的问题。

有关最pythonic方式的任何建议吗?我最初的想法是继承list并将字段定义添加为成员,但似乎python根本不喜欢这个想法。

组合似乎是下一个赌注,但让它像一个正确的list似乎可能是一堆努力让它'正确'。

3 个答案:

答案 0 :(得分:4)

你真正想要的是实现一个新的sequence type,一个可能是可变的。您可以通过实施special methods needed to emulate container types从头开始创建一个,也可以使用合适的collections.abc collection ABC作为基础。

后者可能是最简单的方法,因为ABCs为许多方法提供了实现,作为依赖于必须实现的一些抽象方法的基础版本。

例如,(不可变的)Sequence ABC只要求您提供__getitem____len__的实现;基础ABC实现提供其余的:

from collections.abc import Sequence

class StatusBytes(Sequence):
    def __init__(self, statusbytes):
        self._bytes = statusbytes

    def __getitem__(self, idx_or_name):
        try:
            return self._bytes[idx_or_name]
        except IndexError:
            # assume it is a fieldname
            return FIELDNAMES[idx_or_name]

    def __len__(self):
        return len(self._bytes)

如果您确实需要完整列表实施,包括支持丰富的比较(list_a <= list_b),排序(list_a.sort()),复制[list_a.copy()]和乘法(list_a * 3 ),然后还有collections.UserList() class。此类继承自collections.abc.MutableSequence,并添加了list提供的基本序列ABCs的额外功能。如果您需要额外的功能,请坚持使用基础ABC。

答案 1 :(得分:0)

创建一个继承自collections.UserList的子类,这正是https://docs.python.org/3/library/collections.html#collections.UserList

的子类

答案 2 :(得分:0)

听起来你正在寻找collections.UserList