当前位置: 首页 > 知识库问答 >
问题:

多重继承和调用超级()

郗浩
2023-03-14

我得到一个错误:TypeError:\uuuu init\uuuuuu()正好接受2个参数(给定3个)

当试图从类Top实例化对象时:

超级(Middle1,self)__初始(名称,“中间”)

class Base(object):
    def __init__(self, name, type):
        pass

class Middle1(Base):
    def __init__(self, name):
        super(Middle1, self).__init__(name, "middle1")

class Middle2(Base):
    def __init__(self, name):
        super(Middle2, self).__init__(name, "middle2")

class Middle3(Base):
    def __init__(self, name):
        super(Middle3, self).__init__(name, "middle3")

class Top(Middle1, Middle2, Middle3):
    def __init__(self):
        super(Top, self).__init__("top")

# Here is where it produces the error
if __name__ == '__main__':
    Top()

关于多重继承问题,我还不了解什么?

注意:这是python 2.7

好的,所以我尝试了一些我认为对我的案子有效的方法。这是等效的最终结果,我认为它基本上是通过不调用super而调用每个个体uu init_u_u来强制深度优先。

class Base(object):
    def __init__(self, name, type):
        pass

class Middle1(Base):
    def __init__(self, name, type = "middle1"):
        super(Middle1, self).__init__(name, type)

class Middle2(Base):
    def __init__(self, name, type = "middle2"):
        super(Middle2, self).__init__(name, type)

class Middle3(Base):
    def __init__(self, name, type = "middle3"):
        super(Middle3, self).__init__(name, type)

class Top(Middle1, Middle2, Middle3):
    def __init__(self):
        Middle1.__init__(self, "top")
        Middle2.__init__(self, "top")
        Middle3.__init__(self, "top")

# No errors anymore
if __name__ == '__main__':
    Top()

共有2个答案

公羊子真
2023-03-14

你到底是如何实例化顶级对象的?

鉴于上面的代码,下面的工作正常:

   topObj = Top()
   middleObj = Middle("middle")
   baseObj = Base("base", "type")
宋飞舟
2023-03-14

首先,您必须查看Top的方法解析顺序:

>>> for c in Top.__mro__: print c
...
<class '__main__.Top'>
<class '__main__.Middle1'>
<class '__main__.Middle2'>
<class '__main__.Middle3'>
<class '__main__.Base'>
<type 'object'>

这有助于您查看每个对super的调用所代表的类。

您的错误是认为对super(Middle1,self)的调用是指Middle1的(唯一)基类base。它不是:它指的是self的MRO中Middle1后面的类__类。因为self__类Top,行中的下一个类是Middle2,它的\uuuu init\uuu只接受一个参数。

要从方法中正确使用超级,您需要确保该方法在每个类中采用相同的参数,因为您无法通过查看代码本身来预测哪个类的方法将被调用;这完全取决于启动调用链的对象,这可能是一个您甚至还不知道的类。

有两个帖子我建议阅读:

  • Python的super()被认为是超级的

总之,它们使您能够很好地理解何时可以正确使用super,以及如何避免您在此处看到的问题。

(在完全公开的情况下,我最近没有读过这两篇文章,所以我不会试图总结每一篇文章中提出的建议。)

 类似资料:
  • 主要内容:多继承下的构造函数,命名冲突在前面的例子中,派生类都只有一个基类,称为 单继承(Single Inheritance)。除此之外, C++也支持 多继承(Multiple Inheritance),即一个派生类可以有两个或多个基类。 多继承容易让代码逻辑复杂、思路混乱,一直备受争议,中小型项目中较少使用,后来的 Java、 C#、 PHP 等干脆取消了多继承。 多继承的语法也很简单,将多个基类用逗号隔开即可。例如已声明了类A

  • 本文向大家介绍Java和多重继承,包括了Java和多重继承的使用技巧和注意事项,需要的朋友参考一下 Java不支持多重继承。这意味着一个类不能扩展一个以上的类。因此,跟随是非法的 但是,一个类可以实现一个或多个接口,这帮助Java摆脱了多重继承的可能性。extend关键字仅使用一次,并且父接口在逗号分隔的列表中声明。例如,如果Hockey接口同时扩展了Sports和Event,它将被声明为- 下面

  • 继承是面向对象编程的一个重要的方式,因为通过继承,子类就可以扩展父类的功能。 回忆一下Animal类层次的设计,假设我们要实现以下4种动物: Dog - 狗狗; Bat - 蝙蝠; Parrot - 鹦鹉; Ostrich - 鸵鸟。 如果按照哺乳动物和鸟类归类,我们可以设计出这样的类的层次: 但是如果按照“能跑”和“能飞”来归类,我们就应该设计出这样的类的层次: 如果要把上面的两种分类都包含进来

  • 继承是面向对象编程的一个重要的方式,因为通过继承,子类就可以扩展父类的功能。 回忆一下Animal类层次的设计,假设我们要实现以下4种动物: Dog - 狗狗; Bat - 蝙蝠; Parrot - 鹦鹉; Ostrich - 鸵鸟。 如果按照哺乳动物和鸟类归类,我们可以设计出这样的类的层次: ┌───────────────┐ │

  • 问题内容: 假设我有以下两个课程 如果我启动一个beta类型的新对象,如何执行在alpha类而不是beta中找到的逻辑?我可以使用<-我想知道是否可行。 Eclipse IDE中的自动键入功能使我可以选择从class 或class中进行选择。 问题答案: 你可以做: 注意,这是对父级的引用,但是super()是它的构造函数。

  • 问题内容: 为了完全理解如何解决Java的多重继承问题,我有一个经典的问题需要澄清。 可以说我有类此有子类和我需要做一个类,从扩展和自既是一只鸟和一匹马。 我认为这是经典的钻石问题。从我能理解经典的方式来解决,这是使,和类接口,并实现从他们。 我想知道是否还有另一种方法可以解决仍然可以为鸟和马创建对象的问题。如果有一种能够创造动物的方法,那也很棒,但不是必须的。 问题答案: 你可以为动物类(生物学

  • 假设我有类,它有子类和,我需要创建一个类,它扩展自和,因为既是鸟也是马。 我想这就是经典的钻石问题。据我所知,解决这个问题的经典方法是将、和类作为接口,并从它们实现。 我想知道是否有另一种方法来解决这个问题,在这个方法中,我仍然可以为鸟和马创建对象。如果有一种方法也能创造动物,那将是伟大的,但不是必要的。

  • 本章前面讨论了单一继承,即一个类是从一个基类派生来的。一个类也可以从多个基类派生而来,这种派生称为“多重继承”(multiPle inheritance)。多重继承意味着一个派生类可以继承多个基类的成员,这种强大的功能支持了软件的复用性,但可能会引起大量的歧义性问题。 编程技巧 9.1 多重继承使用得好可具有强大的功能。当新类型与两个或多个现有类型之间存在”是”关系时(即类型A“是”类型B并且也“