2024-04-28 07:53:07 发布
网友
我得到了这个密码:
class A: pass class B(A): pass class C(A): pass class D(A,B): pass d = D()
在Python3中,我遇到了MRO错误。我的意思是因为钻石问题。在Python2没有问题。为什么会这样?钻石的问题到底是什么?在
这是钻石问题!在
当两个类有一个共同的祖先,而另一个类将这两个类都作为基类时,就会出现菱形问题,例如:
class A: def do_thing(self): print('From A') class B(A): def do_thing(self): print('From B') class C(A): def do_thing(self): print('From C') class D(B, C): pass d = D() d.do_thing()
在某些语言中,由于继承的实现方式,当您调用d.do_thing()时,不明确的是要从B重写{},还是要从{}中重写。在
d.do_thing()
B
Python没有这个问题,因为方法的解析顺序。简而言之,当您从多个类继承时,如果它们的方法名冲突,则第一个名为的方法将优先。因为我们指定了D(B, C),所以在C.do_thing之前调用B.do_thing。在
D(B, C)
C.do_thing
B.do_thing
这也是为什么你会有这个问题。考虑一下:因为在您的示例中,B继承自A,因此B的方法将在A之前。方法解析顺序如下:
A
现在,我们用D代替B_derived,因此我们可以用它代替它来得到:
D
B_derived
D -> B -> A
但是,请注意,您还指定了D继承自B之前的A,并且根据上面的规则,A也必须在方法解析顺序的B之前。这意味着我们得到了一个不一致的链:
D -> A -> B -> A
这是为什么会出错,而不是钻石问题。在
(另请参见this answer)。在
这是钻石问题!在
当两个类有一个共同的祖先,而另一个类将这两个类都作为基类时,就会出现菱形问题,例如:
在某些语言中,由于继承的实现方式,当您调用},还是要从{}中重写。在
d.do_thing()
时,不明确的是要从B
重写{Python没有这个问题,因为方法的解析顺序。简而言之,当您从多个类继承时,如果它们的方法名冲突,则第一个名为的方法将优先。因为我们指定了
D(B, C)
,所以在C.do_thing
之前调用B.do_thing
。在这也是为什么你会有这个问题。考虑一下:因为在您的示例中,
^{pr2}$B
继承自A
,因此B
的方法将在A
之前。方法解析顺序如下:现在,我们用
D
代替B_derived
,因此我们可以用它代替它来得到:但是,请注意,您还指定了
D
继承自B
之前的A
,并且根据上面的规则,A
也必须在方法解析顺序的B
之前。这意味着我们得到了一个不一致的链:这是为什么会出错,而不是钻石问题。在
(另请参见this answer)。在
相关问题 更多 >
编程相关推荐