有人在这个网站上遇到了同样的问题,但答案与我遇到的问题无关 继承 - 方法调用
考虑以下类定义。
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作业
答案 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
继承的方法。