5

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

考虑以下类定义。

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()变量,将“调用列表”obj3_calls赋给obj4.f()变量obj4_calls

我理解第一个作业没有问题,obj2_calls = ['C2.f', 'C1.g']
但我正在绞尽脑汁想弄清楚下一个作业。我想既然没有C3.f那个列表,['C1.f']但不幸的是它不是。

澄清一下,这是作业

4

2 回答 2

3

This has to do with the method resolution order (MRO) of your class. (see here for some useful info)

As you stated correctly, there is no C3.f function, so python looks up the f method on the first base-class in the MRO that has f defined. In this case, that is (C1). Now, that method (C1.f) calls self.g(). In this case self is an instance of C3, so of course, self.g calls C3.g since that is the highest g function in the MRO. If you wanted to guarantee that you get C1.g, you'd need to do it explicitly:

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

which also makes a nice lead-in to talking about double-underscore name mangling. Since that is a separate topic though, maybe it's best to only leave a link to some useful documentation.

于 2013-04-22T01:35:17.367 回答
1

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

于 2013-04-22T01:34:01.383 回答