传承麻烦。 - Python

时间:2013-04-22 01:15:35

标签: python inheritance

有人在这个网站上遇到了同样的问题,但答案与我遇到的问题无关 继承 - 方法调用

考虑以下类定义。

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()时,会调用f C1方法调用g方法C1。这可以表示为表单

的“调用列表”
['C1.f', 'C1.g'] 

编写三个赋值语句,分别将obj2.f()的“调用列表”分配给变量obj2_calls,将obj3.f()的“调用列表”分配给变量{{1并将obj3_calls的“调用列表”分配给变量obj4.f()

我理解第一项任务没有问题,它是obj4_calls
但我正在试图找出下一个想法。我想是因为没有obj2_calls = ['C2.f', 'C1.g']列表将是C3.f但不幸的是它不是。{/ p>

要清理,这是IS作业

2 个答案:

答案 0 :(得分:3)

这与您班级的方法解析顺序(MRO)有关。 (有关有用信息,请参阅here

正如您所说的那样,没有C3.f函数,因此python在MRO中定义f的第一个基类上查找f方法。在这种情况下,即(C1)。现在,该方法(C1.f)调用self.g()。在这种情况下,self C3 的一个实例,当然,self.g会调用C3.g,因为这是最高g在MRO中的功能。如果您想保证获得C1.g,则需要明确地执行此操作:

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

这也是讨论双下划线名称修改的一个很好的引导。由于这是一个单独的主题,也许最好只留下link to some useful documentation

答案 1 :(得分:1)

obj3_calls是['C1.f', 'C3.g']。正如您所指出的那样,该类中没有C3.f,但此方法继承自C1。这一个反过来调用self.g,并且由于C3.g 定义的,它会覆盖从C1继承的方法。