在python容器中约束类型和属性

时间:2018-02-21 12:40:44

标签: python oop containers

我想构建一个容器来存储对象,我想约束容器只存储相同类型的对象(类型未定义先验)和不同的属性(例如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)?

1 个答案:

答案 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的静态类型?这不会在运行时引入太多开销。