Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 多重继承:缺少非';实际上并不需要_Python_Python 3.x_Multiple Inheritance - Fatal编程技术网

Python 多重继承:缺少非';实际上并不需要

Python 多重继承:缺少非';实际上并不需要,python,python-3.x,multiple-inheritance,Python,Python 3.x,Multiple Inheritance,由于缺少必需的位置参数arg1,D调用.init时引发TypeError 我知道如何避开这种情况,但我的问题是:为什么会发生这种情况?如果翻转D和B的顺序,错误会在B中抛出,因此无论顺序如何,都会发生错误,并且必须与D和B的写入方式有关,但仅将arg1传递给A没有意义(尽管这确实解决了问题)。我显然不了解Python中的super()或多重继承 (顺便说一句,我再也不会这样做了。这是基于一些现实生活中的代码,我用另一种语言编写了这篇文章,我知道我在这里所做的一切都不是一个好主意。)在Python

由于缺少必需的位置参数arg1,D调用.init时引发TypeError

我知道如何避开这种情况,但我的问题是:为什么会发生这种情况?如果翻转D和B的顺序,错误会在B中抛出,因此无论顺序如何,都会发生错误,并且必须与D和B的写入方式有关,但仅将arg1传递给A没有意义(尽管这确实解决了问题)。我显然不了解Python中的super()或多重继承


(顺便说一句,我再也不会这样做了。这是基于一些现实生活中的代码,我用另一种语言编写了这篇文章,我知道我在这里所做的一切都不是一个好主意。)

在Python中调用
super
时,该语言使用特定的方法来确定要调用的方法。特别是,尽管我们喜欢将继承层次结构可视化为一棵树,但在内部它最终会线性化,以便Python知道调用方法的顺序。具体的线性化过程可以在链接文章中更详细地看到,但在您的案例中,MRO是


class A:
    def __init__(self, arg):
        print("hit A")
        self.arg = 1
        print("close:A")
        return

class B(A):
    def __init__(self, arg, arg1):
        print("hit B")
        super().__init__(arg)
        self.arg1 = arg1
        print("close B")
        return

class D(A):
    def __init__(self, arg, arg1):
        print("hit D")
        super().__init__(arg)
        self.arg1 = 3
        print("done D")
        return

class C(D, B):
    def __init__(self, arg, arg1):
        print("hit C")
        super().__init__(arg, arg1)
        print("done C")
        return


c = C(1,2)
为了总结这个过程(我在这里再次强调了很多),我们从
C
开始。那是我们名单上的头号人物。然后它的第一个父级
D
接着运行。然后,
D
的第一个家长会去下一个。但是
D
的第一个父对象是
A
,它也出现在
B
的层次结构中,因此为了获得拓扑顺序,我们现在需要省略
A
。然后我们进入
B
,这是我们列表中的下一个。然后我们进入
B
的父级,即
A
<代码>A不会出现在列表中未包含的任何其他位置,因此我们可以将其包含在内。最后,我们包括
A
的父对象
对象,我们就完成了

因此,当您从
D
调用
super
时,实际上是在调用
B
的初始值设定项,因为
B
是方法解析顺序中的下一个

如果这是除初始值设定项以外的任何函数,那么更改参数计数将是一种低级趣味,这违反了Liskov替换。特别是对于初始值设定者,我们只需要在使用多重继承时格外小心,以免出现这种特殊情况

C, D, B, A, object