【问题标题】:Use both parents methods in the same method在同一方法中使用两个父方法
【发布时间】:2018-04-02 20:03:36
【问题描述】:

我有一个名为 Cyborg 的类,它继承自另外两个类:HumanRobot。 假设两个父母有自己的方法 Talk(),我可以从 Cyborg 孩子调用这两个方法吗?例如:

class Cyborg(Human, Robot):
    def Talk(self):
        human_properties = Human.Talk()
        robot_properties = Robot.Talk()
        return human_properties + robot_properties

super() 方法不能解决这个问题。

【问题讨论】:

  • 你能给出RobotHuman的(最小)定义吗?
  • 在使用类调用方法时必须显式传递self:分别为Human.talk(self)Robot.talk(self)

标签: python python-3.x multiple-inheritance


【解决方案1】:

如果您正确实现了继承图,则可以使用super 来完成。为此,HumanRobot 都需要一个可以 Talk 的通用基类。

class Thing:
    def Talk(self):
        # Things don't talk, but some more complex things may
        return ''

class Robot(Thing):
    def Talk(self):
        return 'I am a computer!\n' + super().Talk()

class Human(Thing):
    def Talk(self):
        return 'I am an organic being!\n' + super().Talk()

class Cyborg(Human, Robot):
    def Talk(self):
        return super().Talk()

这是一个说话的例子。

>>> Cyborg().Talk()
I am an organic being!
I am a computer!

>>> Robot().Talk()
I am a computer!

>>> Human().Talk()
I am an organic being!

【讨论】:

  • 与@zwer 响应相比,这种方法有什么优势?创建一个不必要的基类只是为了处理它是一个好主意吗?提前致谢!
  • 使用 super 的好处是可维护性。假设您有多个方法需要从 Human 和 Robot 调用方法,并且您将另一个继承添加到您的类。然后,您必须更新执行显式调用的每个方法。使用 super,这是自动完成的。
  • 哦,对,我同意你的看法。以及如何从 Human 和 Robot 返回一些内容以在 Cyborg child 中打印?
  • @norogino 方法super().Talk 可以像任何方法一样返回,因此您可以使用它返回一个字符串。我添加了返回值作为示例。
【解决方案2】:

使用super(),您将在 MRO 链中拾取第一个同名方法,但不能同时使用两者(除非拾取的方法自己调用 super())。如果您想同时选择它们,则必须手动调用它们并明确传递 self 参考:

class Cyborg(Human, Robot):
    def Talk(self):
        human_properties = Human.Talk(self)
        robot_properties = Robot.Talk(self)
        return human_properties + robot_properties

无论如何我都建议不要使用多重继承——虽然它很漂亮而且很有用,而且在极少数情况下是不可替代的,但它带来了太多的陷阱,以至于处理它是不值得的......

【讨论】:

    【解决方案3】:

    不要把Talk当作一个方法,而是把它实现为classmethod,这样一开始就不需要继承:

    class Human:
       @classmethod
       def Talk(cls, *args):
          return 
    
    class Robot:
      @classmethod
       def Talk(cls, *args):
          return
    
    class Cyborg:
      def Talk(self):
         return Human.Talk() + Robot.Talk()
    

    【讨论】:

    • 或者确实是staticmethod
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-17
    • 1970-01-01
    • 2013-08-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多