Python super() - 应该正常工作但没有?

6 投票
3 回答
2654 浏览
提问于 2025-04-16 17:57

根据我所了解的,以及我在网上找到的所有信息,这个应该是可以工作的(但实际上并没有,所以我才来这里问 ;))

class Tigon(Crossbreeds, Predator, Lion):

    def __init__(self):
        super().__init__()
    def printSize(self):
        print("Huge")

“Crossbreeds”和“Predator”都是从“Mammal”这个类继承而来的,而“Lion”则是从“Predator”继承的。编译这些都没问题。我是在使用Python 3.2,不过我也试过之前的版本:

编辑:抱歉,我的帖子有一部分没有显示出来,

我还试过:

class Tigon(Crossbreeds, Predator, Lion):

    def __init__(self):
        super(Tigon, self).__init__()
    def printSize(self):
        print("Huge")

结果都给了我:

class Tigon(Crossbreeds, Predator, Lion):
TypeError: Cannot create a consistent method resolution
order (MRO) for bases Predator, Mammal, Lion

有什么建议吗?

3 个回答

0

应该是 super().__init__(self)

编辑过了:

抱歉,你应该把 Lion 放在前面:

class Tigon(Lion, Predator, Crossbreeds):
    def __init__(self):
        super().__init__()
0

如果我理解你描述的继承模型没错的话,下面是你应该如何定义 Tigon 类:

class Mammal(object):
    def __init__(self):
        super(Mammal, self).__init__()

class Crossbreeds(Mammal):
    def __init__(self):
        super(Crossbreeds, self).__init__()

class Predator(Mammal):
    def __init__(self):
        super(Predator, self).__init__()

class Lion(Predator):
    def __init__(self):
        super(Lion, self).__init__()

class Tigon(Lion, Crossbreeds, Predator):
    def __init__(self):
        super(Tigon, self).__init__()

t = Tigon()

这个替代方案是等价的,因为狮子是捕食者:

class Tigon(Lion, Crossbreeds):
    def __init__(self):
        super(Tigon, self).__init__()

这里有个简单的规则。每个类的构造函数在基类之后被调用,但它们在类定义中必须以相反的顺序出现。此外,重写父类方法的类必须在类定义中优先出现。这意味着如果你想在狮子类中重写捕食者类的方法,狮子类应该在捕食者类之前定义。更详细的解释可以在Jan Hudec的回答中找到。

7

简单来说:不要直接和间接地同时继承同一个基类,但在间接继承后直接继承是可以的。所以不要直接继承 Predator,或者在 Lion 之后继承它。

其实,C3 MRO 似乎找不到一个符合所有规则的顺序。这些规则是:

  • 每个类必须在它的基类之前出现
  • 基类必须按照列出的顺序出现。

你是按顺序继承 CrossbreedsPredatorLion,所以它们的方法也必须按这个顺序调用。但是因为 Lion 继承了 Predator,所以 Lion 的方法必须在 Predator 的方法之前调用。这就造成了矛盾,因此系统说无法创建一致的方法解析顺序。

撰写回答