在多重继承中访问超类方法的更好方法

时间:2011-09-14 12:00:51

标签: python

class Animal(object):
    def eat(self):
        print("I eat all")

class C(object):
    def eat(self):
        print("I too eat")

class Wolf(C, Animal):
    def eat(self):
        print("I am Non Veg")
        super(Wolf, self).eat()
        Animal.eat(self)

w = Wolf()
w.eat()

我正在学习python中的多重继承,我想使用Animal方法从派生类中访问Ceat方法super

调用super类方法C内的eat默认调用,但要调用Animal类方法我使用Animal.eat(self)。我的问题是我怎么能使用Animal方法调用super类方法。

4 个答案:

答案 0 :(得分:6)

如果你想做出理智的多重继承,你需要 everyone 来调用super,除了一个基类,它的职责是不要调用super。使用相同的方法拥有两个完全独立的基类并不是使用OOP理论有意义的事情,并且Python不具备处理好的工具。

您可能会在很多示例中看​​到两个明显独立的基类,但在这些情况下,示例方法通常是__init__,而单个非超级调用基类是{{1 }}

答案 1 :(得分:2)

您无法使用Animal.eat致电supersuper使用Python's Method Resolution Order (MRO)来确定要调用哪个类,C使该MRO中的Animal黯然失色。

在您的示例中,super(Wolf, self).eat()C.eat(self)具有相同的效果。调用Animal.eat(self)有效,但只要继承图保持当前的状态。

由于MRO而不得不调用一个不可用的方法,这表明需要改进类建模。

答案 2 :(得分:1)

super用于在父类中查找。在您的情况下,因为您按照C, Animal的顺序设置继承,所以方法查找的首选顺序如下:

  • 第一个父类
  • 第二个父类

因此super将返回最接近的父方法。

但是,请注意,搜索是以深度优先的方式完成的:

>>> class A(object):
...      def t(self):
...          print 'from A'
>>> class B(object):
...      def t(self):
...          print 'from B'
>>> class C(A):
...      pass
>>> class D(C, B):
...      pass
>>> d = D()
>>> d.t()
from A

答案 3 :(得分:0)

super()使用Method Resolution Order (MRO)来确定调用哪个超类方法。

在多重继承的情况下控制哪个类方法的最佳方法是显式调用它,而不使用super()

或者您可以重新排序子类定义中的超类以更改MRO。这允许您继续使用super(),但牺牲了一些可读性,IMO。

使用super()的示例:

class Wolf(C, Animal):
    def eat(self):
        # C.eat() comes first in the MRO
        super(Wolf, self).eat()

对战:

class Wolf(Animal, C):
    def eat(self):
        # Animal.eat() comes first in the MRO
        super(Wolf, self).eat()
相关问题