我想构建一个容器来存储对象,我想约束容器只存储相同类型的对象(类型未定义先验)和不同的属性(例如name
在示例中以下,这可能是一个索引)。
以下是假设容器是从list
对象派生的预期行为的示例。
obj1 = Foo(name='Jon')
obj2 = Foo(name='Doe')
obj3 = Foo(name='Jon')
obj4 = Bar(name='Bob')
>>> MyContainer()
[]
>>> MyContainer([obj1, obj2])
[Foo(name='Jon'), Foo(name='Doe')]
>>> MyContainer([obj1, obj4])
TypeError: mixed types
>>> MyContainer([obj1, obj3])
ValueError: Same 'name' attribute
我希望这种行为能够保留用于填充容器的方法:__init__
,__add__
,__iadd__
,append
,...
但是,如果可能的话,我希望空容器可以容纳任何类型,只要它们都是一样的。
我想知道实施它的正确方法应该是什么,我正在寻找建议。到目前为止,我考虑从list
推导出来并重写方法,但我对此并不满意。我应该装饰它吗?我应该从头开始构建容器吗?是否已有一个适合我目的的容器(一种dict或pandas.Dataframe)?
答案 0 :(得分:2)
您可以从list
派生您的课程以实现此目的,然后检查可以输入您的实例的所有点,无论输入的是Foo
:
class Foo: pass
class FooList(list):
def __init__(self, elements):
assert all(isinstance(element, Foo) for element in elements)
super().__init__(elements)
def append(self, element):
assert isinstance(element, Foo)
super().append(element)
def __add__(self, other):
return FooList(super().__add__(other)) # will do the checks implicitly
这只会在创建时检查。您现在可以继续并覆盖所有其他点(__iadd__()
,__setitem__()
,...)并在那里引入检查。
我当前的实现仅检查元素的类型。当然,您可以查看更多内容,例如检查您提到的相同名称。
对于这些类型,我不确定这是一个好方法。如何使用Python的静态类型?这不会在运行时引入太多开销。