在Python中的多重继承中,父类A和B的初始化是同时完成的吗? [英] In multiple inheritance in Python, init of parent class A and B is done at the same time?

查看:0
本文介绍了在Python中的多重继承中,父类A和B的初始化是同时完成的吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个关于子类的实例化过程的问题,这个子类分别是从不带arg的父类A和带kwargs的父类B继承的。

在下面的代码中,我不知道为什么在创建Child实例时,执行ParentBset_kwargs()方法,而初始化ParentA

(特别是,为什么结果显示Child receive {}?如何避免此结果?)

如有任何帮助,我们将不胜感激。

谢谢!

class GrandParent:
    def __init__(self):
        print(f"{self.__class__.__name__} initialized")

class ParentA(GrandParent):
    def __init__(self):
        super().__init__()

class ParentB(GrandParent):
    def __init__(self, **kwargs):
        super().__init__()
        self.set_kwargs(**kwargs)
        
    def set_kwargs(self, **kwargs):
        print(f"{self.__class__.__name__} receive {kwargs}")
        self.content = kwargs.get('content')

class Child(ParentA, ParentB):
    def __init__(self, **kwargs):
        ParentA.__init__(self)
        ParentB.__init__(self, **kwargs)

c = Child(content = 3)

结果:

Child initialized
Child receive {}
Child initialized
Child receive {'content': 3}

推荐答案

对于大多数多重继承情况,您都希望超类方法由Python运行库本身按顺序调用。

为此,只需在super()的返回中调用目标方法。

在您的例子中,派生最多的类‘init应该是这样的:

class Child(ParentA, ParentB):
    def __init__(self, **kwargs):
        super().__init__(self, **kwargs)

和所有三个超类__init__方法都将正确运行。请注意,要做到这一点,必须将它们构建为能够在这样的类层次结构中协同工作--这需要两件事:一是任何超类中的每个方法都将自己放入super().method()的一个类--这在您的代码中是可以的。另一种情况是,如果要将参数传递给这些方法(并非所有类都知道),则每个超类中的方法应该只提取它确实知道的参数,并在其自己的super()调用中传递剩余的参数。

所以正确的形式实际上是:

class GrandParent:
    def __init__(self):
        print(f"{self.__class__.__name__} initialized")

class ParentA(GrandParent):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)

class ParentB(GrandParent):
    def __init__(self, **kwargs):
        content = kwargs.pop('content')
        super().__init__(**kwargs)
        self.set_kwargs(content)
        
    def set_kwargs(self, content):
        print(f"{self.__class__.__name__} receive {content}")
        self.content = content

class Child(ParentA, ParentB):
    def __init__(self, **kwargs):
        super.__init__(**kwargs)

c = Child(content = 3)

当您进行super()调用时,进行super()调用时将调用的类是在您创建具有多个父级的类时由Python计算的-因此,即使父级和父级都直接从祖父级继承,当super()调用链从&[2-5]>子级向上冒泡时,Python将从&Parenta";内部知道它的下一个超类是&ClassB";并调用其__init__

查找方法解析顺序的算法相当复杂,对于大多数用例(如果不是全部用例),它只是按其应有的方式工作。它的确切描述可以在这里找到:https://www.python.org/download/releases/2.3/mro/(真的-你不必完全理解它-它处理的角落案例太多了-只需了解它的感觉。)

这篇关于在Python中的多重继承中,父类A和B的初始化是同时完成的吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆