【问题标题】:Python super() with multiple inheritance具有多重继承的 Python super()
【发布时间】:2014-07-01 04:34:30
【问题描述】:

假设我要创建SomeClass,它继承自两个类:

class SomeClass(InheritedClass1, InheritedClass2):

InheritedClass1InheritedClass2 都有同名方法,命名为performLogic

如果我声明super().peformLogic(),我将只从第一个参数/继承类中获得结果。我需要两者的结果,所以我的问题是,有没有办法从InheritedClass1 调用该方法,然后使用super()InheritedClass2 调用该方法?

谢谢。

编辑:

我需要“解决”的类示例是这样构造的(为简洁起见,已简化并跳过了非必要的方法):

class One:
    ...

    def getOutput(self):
        self.output = self.performLogic()
        return self.output

class Two(One):
    ...

    def getFirstValue(self):
        return input()

    def getSecondValue(self):
        return input()

class Three(Two):
    ...

    def performLogic(self):
        (some logic performation based on inputs from class Two methods)

class Four(Two):
    ...

    def performLogic(self):
        (some *different* logic performation based on inputs from class Two methods)

我现在需要做的是实现一个类,该类将执行class Threeclass Four 的逻辑,但只有一对输入值。于是我宣布:

class Five(Three,Four):
    def performLogic(self):
        *and here I got stuck*
        *super().performLogic() will ask me for input values and returns the
        *result of class Three's performLogic()*
        *but what of class Four, I need the result of it's performLogic() with
        *a single pair of input values, too?*

【问题讨论】:

标签: python oop inheritance python-3.x super


【解决方案1】:

super 不是调用父基类中方法的通用替代品;它要求类是合作设计的。这意味着每个 类都需要调用super().performLogic,以防它不是某个类的MRO 的最后一个元素。 最终,在方法解析顺序的末尾必须有一些类不能调用super().peformLogic(),因为它是列表中的 last 类,或者下一个调用将委托给一个类(如object)未定义performLogic。在这种情况下,您必须自己提供这样的根类。

class LogicPerformer:
    def performLogic(self):
        # No call to super; the buck stops here, because object
        # doesn't have this method
        print("In LogicPerformer")

class InheritedClass1(LogicPerformer):

    def performLogic(self):
        print("In InheritedClass1")
        super().performLogic()

class InheritedClass2(LogicPerformer):

    def performLogic(self):
        print("In InheritedClass1")
        super().performLogic()

class SomeClass(InheritedClass1, InheritedClass2):

    def performLogic(self):
        print("In SomeClass")
        super().performLogic()

a = SomeClass()
print(SomeClass.__mro__)
a.performLogic()

【讨论】:

  • 我添加了一个需要“扩展”的类设计的具体示例。
  • 继承是否适合您的代码并不完全清楚。您似乎纯粹将它用于控制流。也许组合(Five 包含对ThreeFour 对象的引用)更合适。
  • 是的,但是Three 对象会要求它自己的一组输入值,以及Four 对象,我只需要使用一组输入来完成它。也许需要更一般的设计改造?
  • 是的。例如,注意Two.getInput() 既不读取也不修改其实例的状态;它几乎没有理由存在于类层次结构中。最好先提示输入,然后将结果值传递给Five.__init__,它可以根据需要使用ThreeFour。您可能实际上不需要任何类,只需要适当定义的函数。
【解决方案2】:

这实际上是一个非常有趣的问题。我认为该语言中没有任何功能允许这样做。您基本上想要做的是使用语言中的方法解析来调用两种方法,其中方法解析总是会解析一种方法。因此,这是无法做到的。如果你想调用两个单独的方法,你需要自己显式地做。

【讨论】:

  • 他有super的正确用例;他只是没有正确使用它。
  • @chepner:不是真的。想要从层次链中的两个不同路径调用相同的方法对于 super 来说并不是一个很好的用例。但是,调用单个已解析的方法是。
  • 哦,看到他的实际用例后评论撤回了。
猜你喜欢
  • 2021-11-28
  • 2022-01-20
  • 2016-02-25
  • 1970-01-01
  • 2018-12-08
  • 2020-07-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多