当前位置: 首页 > 面试题库 >

Python-Python的super()如何处理多重继承?

卢朝
2023-03-14
问题内容

我在使用Python进行面向对象的编程方面非常陌生,并且在理解super()函数(新样式类)时遇到困难,特别是在涉及多重继承时。

例如,如果你有类似的东西:

class First(object):
    def __init__(self):
        print "first"

class Second(object):
    def __init__(self):
        print "second"

class Third(First, Second):
    def __init__(self):
        super(Third, self).__init__()
        print "that's it"

我不明白的是:Third()该类会继承两个构造函数方法吗?如果是,那么哪个将与super()一起运行,为什么?

而如果要运行另一个呢?我知道这与Python方法解析顺序(MRO)有关。


问题答案:

Guido自己在他的博客文章Method Resolution Order(包括两次较早的尝试)中对此进行了合理的详细说明。

在你的示例中,Third()将调用First.__init__。Python从左到右列出,在类的父级中查找每个属性。在这种情况下,我们正在寻找__init__。所以,如果你定义


class Third(First, Second):
    ...

Python将首先查看First,如果First没有该属性,则它将查看Second。

当继承开始跨越路径时(例如,如果First继承自Second),这种情况会变得更加复杂。阅读上面的链接以获取更多详细信息,但是简而言之,Python将尝试维护每个类从子类本身开始在继承列表上出现的顺序。

因此,例如,如果你有:

class First(object):
    def __init__(self):
        print "first"

class Second(First):
    def __init__(self):
        print "second"

class Third(First):
    def __init__(self):
        print "third"

class Fourth(Second, Third):
    def __init__(self):
        super(Fourth, self).__init__()
        print "that's it"
MRO将是 [Fourth, Second, Third, First].

顺便说一句:如果Python无法找到一致的方法解析顺序,它将引发异常,而不是退回到可能使用户感到惊讶的行为。

编辑以添加一个模棱两可的MRO的示例:

class First(object):
    def __init__(self):
        print "first"

class Second(First):
    def __init__(self):
        print "second"

class Third(First, Second):
    def __init__(self):
        print "third"

是否应Third的MRO是[First, Second][Second, First]?没有明显的期望,Python会引发错误:

TypeError: Error when calling the metaclass bases
    Cannot create a consistent method resolution order (MRO) for bases Second, First

编辑:我看到几个人争辩说上面的示例缺少super()调用,所以让我解释一下:这些示例的重点是说明MRO的构造方式。它们不打算打印“第一\第二\第三”或其他内容。你可以并且应该当然使用该示例,添加super()调用,看看会发生什么,并且对Python的继承模型有更深入的了解。但我的目标是保持简单,并说明MRO的构建方式。正如我所解释的那样:

>>> Fourth.__mro__
(<class '__main__.Fourth'>,
 <class '__main__.Second'>, <class '__main__.Third'>,
 <class '__main__.First'>,
 <type 'object'>)


 类似资料:
  • 本文向大家介绍Python的super()如何与多重继承一起使用?,包括了Python的super()如何与多重继承一起使用?的使用技巧和注意事项,需要的朋友参考一下 在解释super() 之前,我们首先需要了解多重继承的概念。 多重继承:意味着一个子类可以继承多个父类。 在以下示例中,子类从父类继承了属性方法。 示例 输出结果 在下面的示例中,显示了(即)   super()具有多个继承 sup

  • 问题内容: 在Python中,如何选择要调用的Parent方法?假设我要调用父ASDF2的方法。似乎我必须在super()中指定 ASDF1 。如果要调用ASDF3 ,则必须指定 ASDF2 吗? 在我看来是疯子。我究竟做错了什么? 问题答案: 那不是为了什么 超级基本上是按照特定顺序选择一个(或全部)父母。如果您只想调用单亲方法,请执行此操作

  • 问题内容: 我一直在阅读有关Python的多处理模块的信息。我仍然认为我对它可以做什么没有很好的了解。 假设我有一个四核处理器,并且我有一个包含1000000个整数的列表,我想要所有整数的总和。我可以简单地做: 但这仅将其发送到一个内核。 是否有可能使用多处理模块将数组划分为多个,并让每个核获得其部分的总和并返回值,以便可以计算总和? 就像是: 任何帮助,将不胜感激。 问题答案: 是的,可以对多个

  • 前面不止一次讲过, Python 中子类会继承父类所有的类属性和类方法。严格来说,类的构造方法其实就是实例方法,因此毫无疑问,父类的构造方法,子类同样会继承。 但我们知道,Python 是一门支持多继承的面向对象编程语言,如果子类继承的多个父类中包含同名的类实例方法,则子类对象在调用该方法时,会优先选择排在最前面的父类中的实例方法。显然,构造方法也是如此。 举个例子: 运行结果,结果为: 我是人,

  • 问题内容: 这个问题可能已经有人提出过,而且回答的可能性更大,但是我不知道在哪里可以找到它。 问题:我有一个用于pythonflask的路由器,该路由器需要花费一些时间来处理每个调用的数据。我需要使对路由的每个调用本身就是一个线程,因此它不必等待请求被加载。 问题答案: Flask带有内置的开发Web服务器,但是你不应该在生产环境中使用它。 为了获得一些很酷的功能,例如为每个请求和静态文件服务提供

  • 问题内容: 如何在没有多线程的情况下在python中运行多个进程?例如考虑以下问题: 我们必须制作一个Gui,它具有一个启动一个函数的开始按钮(例如,打印所有整数),还有一个停止按钮,以便单击该按钮可以停止该函数。 如何在Tkinter中做到这一点? 问题答案: 然后,您需要将小部件与启动工作线程的函数绑定在一起。例如: 通过这种方法,您只能通过更改其值来优雅地结束线程。注意,使用多个线程可避免在