这是我的一般问题空间:
我有一个通过I2C设备的字节/位协议。
我有一个命令的“数据库”,可以完整地描述所有位域类型,值和枚举。
我有一个使用数据库的类和一个i2c驱动程序/交易器,这样我就可以调用命令并获得响应。
MyProtocol = Protocol('database.xml',I2CDriver())
theStatus = MyProtocol.GET_STATUS()
为GET_STATUS命令创建正确的字节流,通过i2c发送它并将响应作为字节数组返回。我可以让它在GET_STATUS()实现中打印响应,但我想将该行为移动到返回对象,而不是在命令中。
我希望我的返回对象是“聪明的”:theStatus
需要包含字节列表/数组以及对其字段定义的引用。
我希望theStatus
像列表/ bytearray一样,所以我可以直接检查字节。我不关心切片是否只是字节列表或bytearray。一旦它们被切掉,它们只是字节。
我希望'theStatus'能够打印print(theStatus)
,并且可以打印状态中的所有字段。一旦我确定了一个允许我访问字节和数据库的可行数据结构,我对如何实现这一点感到很自在。
我想通过theStatus
或theStatus.FIELDNAME
之类的字段来检查theStatus['FIELDNAME']'
。同样的事情:一旦我有一个可行的数据结构,其中包含字节数组和数据库作为成员,我可以实现这一点。
问题是我不知道“正确”的数据结构导致最少的问题。
有关最pythonic方式的任何建议吗?我最初的想法是继承list
并将字段定义添加为成员,但似乎python根本不喜欢这个想法。
组合似乎是下一个赌注,但让它像一个正确的list
似乎可能是一堆努力让它'正确'。
答案 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。