Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/280.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 - Fatal编程技术网

Python 多重继承;“破碎的”;钻石

Python 多重继承;“破碎的”;钻石,python,python-3.x,Python,Python 3.x,我在探索当两个父类中的一个不从公共基类继承时,多重继承是如何工作的。节目如下: '''Demomstration of MRO on 'broken' diamonds''' class Base: def hello(self): print('Base') class Left(Base): def hello(self): print('Left') super().hello() class Right: de

我在探索当两个父类中的一个不从公共基类继承时,多重继承是如何工作的。节目如下:

'''Demomstration of MRO on 'broken' diamonds'''

class Base:
    def hello(self):
        print('Base')

class Left(Base):
    def hello(self):
        print('Left')
        super().hello()

class Right:
    def hello(self):
        print('Right')
        super().hello()

class Child1(Left, Right):
    '''Class has right edge missing'''
    def hello(self):
        print('Child1')
        super().hello()

class Child2(Right, Left):
    '''Class has left edge missing'''
    def hello(self):
        print('Child2')
        super().hello()

print(help(Child1))
print(help(Child2))

print('Child1 output:')
print('==============')
Child1().hello()
print('\nChild2 output:')
print('==============')
Child2().hello()
help()
指出,在第一种情况下,MRO将:

 |      Child1
 |      Left
 |      Base
 |      Right
 |      builtins.object
而在第二种情况下(请注意:
Right
实际上位于左侧):

但是
hello()
函数的输出是:

Child1 output:
==============
Child1
Left
Base

Child2 output:
==============
Child2
Right
Left
Base
因此,在第一种情况下,
Right
类被完全跳过!这几乎就像口译员无法接触到它,因为没有任何连接可以跟随


我可以理解,这可以通过使用C3线性化算法来解释,但是层次结构中的一个类被忽略,而镜像情况下则没有,这不是有点奇怪吗?

您的
库。hello
函数在这个测试中“被破坏”。考虑你的MRO中的<代码> hello >代码>:

Child1.hello
    print('Child1')  # PRINTED
    super().hello()  # super() -> Left
Left.hello
    print('Left')    # PRINTED
    super().hello()  # super() -> BASE
Base.hello
    print('Base')  # PRINTED
    # no call to super()!!!
Right.hello    # NEVER CALLED
    print('Left')
    super().hello()  # super() -> object
builtins.object.hello

所以基本上,一旦
super().hello
解析为
Base.hello
,那么
super
链就停止了<代码>基本。hello错过了对
super
的调用,无法前进到
Right
。因此,
Right.hello
不会被调用,即使
Right
在MRO中。

您的
Base.hello
函数在该测试中“已损坏”。考虑你的MRO中的<代码> hello >代码>:

Child1.hello
    print('Child1')  # PRINTED
    super().hello()  # super() -> Left
Left.hello
    print('Left')    # PRINTED
    super().hello()  # super() -> BASE
Base.hello
    print('Base')  # PRINTED
    # no call to super()!!!
Right.hello    # NEVER CALLED
    print('Left')
    super().hello()  # super() -> object
builtins.object.hello

所以基本上,一旦
super().hello
解析为
Base.hello
,那么
super
链就停止了<代码>基本。hello错过了对
super
的调用,无法前进到
Right
。因此,
Right.hello
不会被调用,即使
Right
在MRO中。

您使用的是python2还是python3?在蟒蛇3中没有“碎钻石”。你总是把
对象
放在上面,所以最后总会有一颗钻石。但是,如果您使用的是python2,那么您使用的是不推荐使用的旧式类,而且不使用C3线性化。您可以从
帮助
中看到MRO中的问题:
Base
位于
Right
之前,但不调用
super().hello()
@dotslash。。。那么<代码>打印(“Hello”)
是有效的python2,并且打印的内容与python3中的内容完全相同。应该让我意识到它是python3的东西是在旧式类中调用
super
,而且
super
没有参数。@dotslash按照这个顺序,直到它到达
基。hello
,它不调用
super
。所以就到此为止。“几乎就像解释器无法接触到它,因为没有要遵循的连接”-不,因为代码没有告诉它要遵循连接!在python2中,
()
不是函数调用的一部分,它们只是对不起任何作用的括号进行分组。与编写
x=(5)
相同,这与
x=5
相同。此更改适用于
打印(1,2)
。在python3中,它生成
12
,因为它是一个带有两个参数的函数调用;在python2中,它生成
(1,2)
,因为它只打印元组。然而,在代码中,您总是使用单个参数。您使用的是python2还是python3?在蟒蛇3中没有“碎钻石”。你总是把
对象
放在上面,所以最后总会有一颗钻石。但是,如果您使用的是python2,那么您使用的是不推荐使用的旧式类,而且不使用C3线性化。您可以从
帮助
中看到MRO中的问题:
Base
位于
Right
之前,但不调用
super().hello()
@dotslash。。。那么<代码>打印(“Hello”)
是有效的python2,并且打印的内容与python3中的内容完全相同。应该让我意识到它是python3的东西是在旧式类中调用
super
,而且
super
没有参数。@dotslash按照这个顺序,直到它到达
基。hello
,它不调用
super
。所以就到此为止。“几乎就像解释器无法接触到它,因为没有要遵循的连接”-不,因为代码没有告诉它要遵循连接!在python2中,
()
不是函数调用的一部分,它们只是对不起任何作用的括号进行分组。与编写
x=(5)
相同,这与
x=5
相同。此更改适用于
打印(1,2)
。在python3中,它生成
12
,因为它是一个带有两个参数的函数调用;在python2中,它生成
(1,2)
,因为它只打印元组。然而在你的代码中你总是使用一个参数。接下来的问题是:如果你只是盲目地在
Base
中使用
super
,有时你最终会调用
对象。你好
,结果很糟糕@我刚刚遇到了这样的事情!在base中粘贴
super()
到达
右侧
,然后抛出
AttributeError
,因为我想,现在树已经被遍历了,没有更多的
super()
了。我在哪里可以找到一些关于使用
super()
的指南?@jornsharpe我希望你能推荐一些博客文章,不过还是谢谢你@dotslash是经典之作,你可以通过…@jornsharpe找到它。我知道这篇文章/演讲,但认为它对像我这样的傻瓜没有帮助P:我去看看。谢谢后续问题:如果你只是在
Base
中盲目地
super
,有时你最终会调用
对象。你好
,结果是灾难性的@我刚刚遇到了这样的事情!在base中粘贴
super()
到达
右侧
,然后抛出
AttributeError
,因为我猜,现在树已经被遍历,t