多重继承中更好地访问父类方法的方法

15 投票
4 回答
14048 浏览
提问于 2025-04-17 02:17
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中的多重继承,想从派生类中使用super方法来访问AnimalC类的eat方法。

默认情况下,super会调用C类的eat方法,但我想调用Animal类的方法时用了Animal.eat(self)。我的问题是,如何通过super方法来调用Animal类的方法。

4 个回答

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
2

你不能用 super 来调用 Animal.eatsuper 是根据 Python的方法解析顺序(MRO) 来决定调用哪个类的方法,而在这个顺序中,C 类覆盖了 Animal 类。

在你的例子中,super(Wolf, self).eat()C.eat(self) 的效果是一样的。调用 Animal.eat(self) 是可以的,但前提是继承关系保持不变。

如果你需要调用一个因为 MRO 而无法使用的方法,这说明你的类设计需要改进。

8

如果你想要合理地使用多重继承,你需要确保每个类都在调用super,除了恰好一个基类,这个基类的任务就是不调用 super。拥有两个完全独立的基类,并且它们有相同的方法,这在面向对象编程的理论中是没有意义的,而且 Python 也没有很好的工具来处理这种情况。

你可能会在很多例子中看到两个看似独立的基类,但在这些例子中,通常使用的方法是__init__,而唯一一个不调用 super 的基类就是object

撰写回答