【问题标题】:What to consider before subclassing list?在子类列表之前要考虑什么?
【发布时间】:2011-04-26 03:31:42
【问题描述】:

我最近遇到了一个编码问题,有人查看代码说子类化列表不好(我的问题与该类无关)。他说你不应该这样做,而且它带来了一堆不好的副作用。这是真的吗?

我在问 list 通常对子类是否不好,如果是,原因是什么。或者,在 Python 中对列表进行子类化之前我应该​​考虑什么?

【问题讨论】:

  • 子类列表本质上并不坏,但在很多情况下它确实不是您想要做的。除非您提供具体信息,否则我们无法回答是否属于这种情况。

标签: python list subclassing


【解决方案1】:

collections 模块中提供的abstract base classes,尤其是MutableSequence,在实现类似列表的类时很有用。这些在 Python 2.6 及更高版本中可用。

使用 ABC,您可以实现类的“核心”功能,它将提供逻辑上取决于您定义的方法。

例如,在collections.Sequence 派生类中实现__getitem__ 就足以为您的类提供__contains____iter__ 和其他方法。

您可能仍希望使用包含的列表对象来完成繁重的工作。

【讨论】:

【解决方案2】:

子类化list 没有任何好处。这些方法都不会使用您覆盖的任何方法,因此您可能会遇到意外错误。此外,使用self.append 而不是self.foos.append 或特别是self[4] 而不是self.foos[4] 来访问您的数据常常会让人感到困惑。您可以制作完全像列表或(更好)无论多么像您真正想要的列表的东西,同时只需对object进行子类化。

【讨论】:

  • 如果我们想给一个列表添加一个属性怎么办?例如,假设我们有 mylist = []。我们想要类似 mylist.x = 3 的东西。
  • @Selinap,如果我希望我的状态包含一些东西的列表和一个 int,我仍然可能会使用组合。使用继承会导致书写混乱,使用混乱,并不会真正为您带来任何好处。
  • 这似乎不适用于 python 3。为此目的明确包含 collections.UserList。它甚至表明现在可以从列表中进行子类化:“对此类的需求已部分被直接从列表中子类化的能力所取代;” (我知道这是一个老话题,上面的 cmets 在编写时可能是正确的,只是想让现在发现这个问题的人清楚)
  • @Claude,有些人喜欢这样一个抽象的事实,即自从引入新式类以来,可以对内置函数进行子类化(没有抛出错误),但事实仍然是它实际上是无用的.子类列表有大量未定义的行为,真正的行为是无用的“没有什么是虚拟的”。在 Python 2 或 Python 3 中继承 collections.MutableSequenceobject(2)/nothing(3) 更为有用。
【解决方案3】:

我想我要问自己的第一个问题是,“我的新对象真的是一个列表吗?”。它像列表一样走路,像列表一样说话吗?或者是别的什么?

如果是列表,那么所有标准的列表方法都应该有意义。

如果标准列表方法没有意义,那么您的对象应该包含一个列表,而不是一个列表。

在旧的 python (2.2?) 中,由于各种技术原因,子类列表是一个坏主意,但在现代 python 中它很好。

【讨论】:

  • +1 仅在真正 100% 有意义时才继承,否则 compose。
  • 至于副作用,他有点过时了?数据包含在一个列表中,但是为了做很多事情,我需要忽略很多其他特定的方法。
  • 是的,继承“is-a”关系,编写几乎所有其他内容。
【解决方案4】:

尼克是正确的。 此外,虽然我不会说 Python,但在其他 OO 语言(Java、Smalltalk)中,将列表子类化是一个坏主意。一般应避免继承,而应使用委托组合。

相反,您创建一个容器类并将调用委托给列表。容器类具有对列表的引用,您甚至可以在自己的方法中公开列表的调用和返回。 这增加了灵活性,并允许您稍后更改实现(不同的列表类型或数据结构)而不破坏任何代码。如果您希望您的列表执行不同的列表类型的事情,那么您的容器可以执行此操作并将普通列表用作简单的数据结构。 想象一下,如果您有 47 种不同的列表用途。你真的要维护 47 个不同的子类吗? 相反,您可以通过容器和接口来做到这一点。一个类来维护并允许人们通过接口调用您的新方法和改进方法,而实现保持隐藏。

【讨论】:

    猜你喜欢
    • 2016-07-19
    • 1970-01-01
    • 2017-09-09
    • 1970-01-01
    • 2016-10-13
    • 1970-01-01
    • 2014-10-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多