【问题标题】:Is it bad practice to inherit from list? [duplicate]从列表继承是不好的做法吗? [复制]
【发布时间】:2021-10-27 22:32:28
【问题描述】:

在我处理的许多问题中,我发现我将有一个自定义类,然后是一个容器类,用于存储这些对象和作用于类中所有对象的方法。

例如,考虑一个曲线类和一个容器。

class Curve:
    def __init__(self, args):
        self.label

    def getLength(self):
        # code that gets length
...

curves = [curve1, curve2, ..., ]

class CurvesContainer:
    def __init__(self, curves):
        self.curves = curves
        ...

    def setLabels(self, labels):
        for curve, label in zip(self.curves, labels):
            curve.label = label 

    def getLengths(self):
        lengths = []
        for curve in self.curves:
            lengths.append(curve.getLength())
        return lengths

curve1 = container.curves[1]

但是,如果我们使用此设置,我们最终会调用container.curves/self.curves 很多 - 有点丑陋!

似乎一种重构方法是从list继承如下:

class CurvesContainer(list):
    def __init__(self, curves):
        super().__init__(curves)

    def setLabels(self, labels):
        for curve, label in zip(self, labels):
            curve.label = label 

    def getLengths(self):
        lengths = []
        for curve in self:
            lengths.append(curve.getLength())
        return lengths

curve1 = container[1]

但是,我认为这在实践中做得并不多 - 我想知道这是否出于某种原因是不好的形式?

【问题讨论】:

  • 这个类似乎没有充分的理由存在。它不代表有意义的抽象或提供有用的功能。您可以使用普通列表。
  • 这是prefer composition over inheritance问题的又一次迭代

标签: python list containers


【解决方案1】:

composition over inheritance的通用OOP原理:

在面向对象编程中组合优于继承的原则是,类应该通过组合(通过包含实现所需功能的其他类的实例)而不是从基类或父类继承来实现多态行为和代码重用。这是 OOP 中经常提到的原则,例如在颇具影响力的《设计模式》一书中(1994 年)。

一个问题是list 的所有返回新列表的方法仍然返回一个列表。如果你切片新的CurvesContainer,你会得到一个列表。如果你连接两个CurvesContainers,你会得到一个列表。等等。如果这不是您想要的,您需要自己重新实现所有这些方法。

【讨论】:

    【解决方案2】:

    这不是一个坏习惯,实际上是对类继承的一种很好的利用。

    另一种选择是实现__iter__ 方法,但它只会启用列表的迭代方面。

    您的示例非常有效良好做法

    【讨论】:

    • 请添加更多详细信息以扩展您的答案,例如工作代码或文档引用。
    • 容器应该实现__iter__,而不是__next__
    猜你喜欢
    • 2011-10-23
    • 2015-06-13
    • 2012-08-06
    • 2023-03-07
    • 2016-11-10
    • 2011-08-22
    • 2023-03-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多