多重继承中更好地访问父类方法的方法
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
方法来访问Animal
和C
类的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.eat
。super
是根据 Python的方法解析顺序(MRO) 来决定调用哪个类的方法,而在这个顺序中,C
类覆盖了 Animal
类。
在你的例子中,super(Wolf, self).eat()
和 C.eat(self)
的效果是一样的。调用 Animal.eat(self)
是可以的,但前提是继承关系保持不变。
如果你需要调用一个因为 MRO 而无法使用的方法,这说明你的类设计需要改进。
8
如果你想要合理地使用多重继承,你需要确保每个类都在调用super
,除了恰好一个基类,这个基类的任务就是不调用 super。拥有两个完全独立的基类,并且它们有相同的方法,这在面向对象编程的理论中是没有意义的,而且 Python 也没有很好的工具来处理这种情况。
你可能会在很多例子中看到两个看似独立的基类,但在这些例子中,通常使用的方法是__init__
,而唯一一个不调用 super 的基类就是object
。