我最近正在处理我遇到的编码问题,有人看着代码说子类列表很糟糕(我的问题与该类无关)。他说你不应该这样做,而且它带来了一堆不好的副作用。这是真的吗?
我在询问列表是否通常对子类不好,如果是,那么原因是什么。或者,在Python中对列表进行子类化之前我应该考虑什么?
答案 0 :(得分:17)
abstract base classes模块中提供的collections
,尤其是MutableSequence
,在实现类似列表的类时非常有用。这些在Python 2.6及更高版本中可用。
使用ABCs,您可以实现类的“核心”功能,它将提供逻辑上取决于您定义的内容的方法。
例如,在__getitem__
派生类中实施collections.Sequence
就足以为您的班级提供__contains__
,__iter__
和其他方法。
您可能仍希望使用包含的列表对象来完成繁重的工作。
答案 1 :(得分:17)
继承list
没有任何好处。这些方法都不会使用您覆盖的任何方法,因此您可能会遇到意外错误。此外,执行self.append
而不是self.foos.append
或特别是self[4]
而不是self.foos[4]
来访问您的数据时,常常会感到困惑。你可以创建一些像一样或(更好)的东西,但是就像你真正想要的列表而只是继承
object
。
答案 2 :(得分:11)
我认为我问自己的第一个问题是,“我的新对象真的是一个列表吗?”。它像列表一样走路,像列表那样说话吗?或者是别的什么?
如果它是一个列表,那么所有标准列表方法都应该有意义。
如果标准列表方法没有意义,那么您的对象应该包含一个列表,而不是列表。
在旧的python(2.2?)中,由于各种技术原因,子类别列表是一个坏主意,但在现代的python中它很好。
答案 3 :(得分:6)
尼克是对的。 此外,虽然我不能说Python,但在其他OO语言(Java,Smalltalk)中,对列表进行子类化是一个坏主意。一般应该避免继承,而是使用委托组合。
相反,您创建一个容器类并将调用委托给列表。容器类具有对列表的引用,您甚至可以在自己的方法中公开列表的调用和返回。 这增加了灵活性,允许您稍后更改实现(不同的列表类型或数据结构),而不会破坏任何代码。如果您希望列表执行不同的listy类型的事情,那么您的容器可以执行此操作并使用普通列表作为简单的数据结构。 想象一下,如果你有47种不同的列表用途。你真的想要维护47个不同的子类吗? 相反,你可以通过容器和接口来做到这一点。一个类维护并允许人们通过接口调用新的和改进的方法,并且实现仍然隐藏。