最近我在处理一个编码问题时,有人看着我的代码说子类化list是不好的(我的问题与该类无关)。他说你不应该这么做,而且会带来许多副作用。这是真的吗?
我的问题是:Python中是否通常不建议子类化list,如果是,原因是什么?或者,在子类化list之前我应该考虑什么?
最近我在处理一个编码问题时,有人看着我的代码说子类化list是不好的(我的问题与该类无关)。他说你不应该这么做,而且会带来许多副作用。这是真的吗?
我的问题是:Python中是否通常不建议子类化list,如果是,原因是什么?或者,在子类化list之前我应该考虑什么?
在编写类似于列表的类时,collections
模块中提供的 抽象基类,特别是 MutableSequence
,非常有用。这些可用于 Python 2.6 及更高版本。
使用 ABCs,您可以实现类的“核心”功能,并提供逻辑上依赖于您定义内容的方法。
例如,在派生自 collections.Sequence
的类中实现 __getitem__
就足以为您的类提供 __contains__
、__iter__
和其他方法。
您可能仍然希望使用包含的列表对象来完成繁重的工作。
list
没有任何好处。覆盖其中的任何方法都不会被使用,因此可能会导致意外的错误。此外,在访问数据时,像self.append
而不是self.foos.append
或尤其是self[4]
而不是self.foos[4]
之类的操作通常很令人困惑。您可以通过仅子类化object
来创建与列表完全相同的东西或(更好)与列表相似程度符合您的要求。collections.UserList
。甚至建议现在可以从list中进行子类化:“现在直接从list进行子类化已经部分取代了这个类的需求;”。(我知道这是一个旧话题,上面的评论可能在写作时是正确的,只是想让现在看到这个问题的人清楚地了解这一点)。 - Claudecollections.MutableSequence
或object
(2)/nothing(3)更加有用。 - Mike Grahamlist
而不是重新实现多个list
方法和迭代。如果UserList
解决了这些问题,那就很好,但是OO编程到底怎么了,为什么每个人都想放弃子类化?而且,UserList
文档现在说:“这个类的需求部分被直接从列表中进行子类化的能力所取代;然而,这个类可能更容易使用,因为底层列表可以作为属性访问。” - NeilG我认为我首先要问自己的问题是:“我的新对象真的是一个列表吗?”。它是否像列表一样工作和表现?或者它是其他什么东西?
如果它是列表,那么所有标准的列表方法都应该是有意义的。
如果标准的列表方法不适用,那么你的对象应该包含一个列表,而不是成为一个列表。
在旧版本的Python(2.2?)中,从列表进行子类化在技术上存在各种问题,但在现代Python中没有问题。