方法解析顺序(MRO)在该Python代码中的工作方式

2024-09-30 01:29:22 发布

您现在位置:Python中文网/ 问答频道 /正文

class parent:
    def __init__(self):
        self.a=2
        self.b=4
    def form1(self): 
        print("calling parent from1")
        print('p',self.a+self.b)
 
class child1(parent):
    def __init__(self):
        self.a=50
        self.b=4
    def form1(self):
        print('bye',self.a-self.b)
    def callchildform1(self):
        print("calling parent from child1")
        super().form1()
 
class child2(parent):
    def __init__(self):
        self.a=3
        self.b=4
    def form1(self):
        print('hi',self.a*self.b)
    def callchildform1(self):
        print("calling parent from child2")
        super().form1()
 
class grandchild(child1,child2):
    def __init__(self):
        self.a=10
        self.b=4
    def callingparent(self):
        super().form1()
 
g=grandchild()
g.callchildform1()

在上面的代码中,当我调用g.callchildform1()时,根据MRO规则,将首先在同一个类中搜索该方法,然后搜索第一个父级(这里是child1),然后搜索第二个父级(child2)。 正如预期的那样,它调用child1.callchildform1()并执行第一行print("calling parent from child1")。但是在这之后,我期望下一行super().form1()将被执行,它将调用parent.form1(),但是这没有发生。相反,正在调用child2.form1()。请解释为什么会发生这种情况


Tags: fromselfinitdefclassparentprintsuper
1条回答
网友
1楼 · 发布于 2024-09-30 01:29:22

{a1}对{}的工作原理有很好的解释:

super([type[, object-or-type]])

Return a proxy object that delegates method calls to a parent or sibling class of type. This is useful for accessing inherited methods that have been overridden in a class.

The object-or-type determines the method resolution order to be searched. The search starts from the class right after the type.

For example, if __mro__ of object-or-type is D -> B -> C -> A -> object and the value of type is B, then super() searches C -> A -> object.

super()等价于表达式super(__class__, self),其中__class__是一个类对象,在其方法中调用super()。例如,grandchild.callingparent(self)中的super()本质上是super(grandchild, self)。而super()内的child1.callchildform1(self)函数是super(child1, self)

MROgrandchild(<grandchild>, <child1>, <child2>, <parent>, <object>)。因此,根据上述文档摘录,当在child1.callchildform1()中调用super().form1()时,相当于super(child1, self),对form1方法的搜索从MRO序列中child1之后的类开始,与form1方法匹配的第一个类是child2

发生这种情况的原因是您使用的是菱形继承结构和MRO下面的principles

with multiple inheritance hierarchies, the construction of the linearization is more cumbersome, since it is more difficult to construct a linearization that respects local precedence ordering and monotonicity.

在设计这样的层次结构时,需要遵循协作继承的方法,在这个已经很经典的article中可以找到一个解释

相关问题 更多 >

    热门问题