继承问题。 - Python

问题描述:

有人在这个网站上有这个完全相同的问题,但答案并没有涉及到我有麻烦的部分。
继承 - 方法调用继承问题。 - Python

请考虑以下类定义。

class C1(object): 
    def f(self): 
     return 2*self.g() 

    def g(self): 
     return 2 

class C2(C1): 
    def f(self): 
     return 3*self.g() 


class C3(C1): 
    def g(self): 
     return 5 

class C4(C3): 
    def f(self): 
     return 7*self.g() 

obj1 = C1() 
obj2 = C2() 
obj3 = C3() 
obj4 = C4() 

对于这个问题你要考虑哪些方法当f方法被调用时调用。例如,当调用obj1.f()时,将调用C1f方法,该方法调用C1g方法。这可以表示为形式

['C1.f', 'C1.g'] 

写三篇赋值语句,分别指定为obj2.f()给变量obj2_calls的“呼叫列表”的“呼叫名单”,分配为obj3.f()到“呼叫清单”变量obj3_calls并将obj4.f()的“呼叫列表”分配给变量obj4_calls

我没有理解第一项任务,它是obj2_calls = ['C2.f', 'C1.g']
但我正在试图找出下一个我的脑袋。我想因为没有C3.f该名单将是['C1.f'],但不幸的是它不是。

只是为了澄清,这是功课

+3

为每个函数添加一些'print'语句来找出真正发生的事情。 – 2013-04-22 01:19:33

+0

如果你输入C3.f,你会看到c3.f ,这意味着它是类C3的一部分 – Greg 2013-04-22 01:25:31

+0

嗨,大家非常有帮助,使用print我有正确的答案。但是我比理解代码更常用。 我还是想明白为什么答案是 obj3_calls = ['C1.f','C3.g']。'c1.f' – 2013-04-22 01:31:54

obj3_calls为['C1.f', 'C3.g']。正如您指出的那样,该类中没有C3.f,但是此方法从C1继承。这一个依次调用self.g,并且因为C3.g定义的,它将覆盖从C1继承的方法。

这与您班级的方法解析顺序(MRO)有关。 (见here一些有用的信息)

正如你正确地指出,没有C3.f功能,所以Python中查找f方法上最初的基类中已定义f的MRO。在这种情况下,即(C1)。现在,该方法(C1.f)称为self.g()。在这种情况下,selfC3的一个实例,因此当然,self.g调用C3.g,因为这是MRO中的最高g函数。如果你想保证你得到C1.g,你需要明确地做到这一点:

class C1(object): 
    def f(self): 
     return 2*C1.g(self) 
    def g(self): 
     return 5 

这也使得一个很好的引入到谈论双下划线名字改编。因为这是一个单独的主题,所以最好只留下link to some useful documentation

+0

太棒了,谢谢你,并感谢大家的帮助。我现在知道了 – 2013-04-22 01:39:59