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()'calling list' forを変数obj2_callsに代入し、'calling list' forobj3.f()を変数 にobj3_calls代入し、'calling list' for を変数 に代入する 3 つの代入ステートメントをそれぞれ記述しobj4.f()ますobj4_calls

最初の課題を理解するのに問題はありませんが、次の課題を理解obj2_calls = ['C2.f', 'C1.g']
しようとして頭を悩ませています。C3.fリストがあるとは思っていなかったので['C1.f']、残念ながらそうではありませんでした。

念のため、これは宿題です

4

2 に答える 2

3

これは、クラスのメソッド解決順序 (MRO) に関係しています。(役立つ情報 については、こちらを参照してください)

あなたが正しく述べたように、C3.f関数がないため、pythonは定義さfれた MRO の最初の基本クラスでメソッドを検索します。fこの場合、それは ( C1) です。さて、そのメソッド ( C1.f) は を呼び出しますself.g()。この場合self 、 は のインスタンスですC3。もちろん、これは MROの最上位の関数であるため、 をself.g呼び出します。を取得することを保証したい場合は、明示的に行う必要があります。C3.ggC1.g

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

これは、アンダースコアが 2 つある名前マングリングについて話す良いきっかけにもなります。ただし、それは別のトピックであるため、いくつかの有用なドキュメントへのリンクのみを残すのが最善かもしれません.

于 2013-04-22T01:35:17.367 に答える
1

obj3_calls は['C1.f', 'C3.g']. ご指摘のとおりC3.f、そのクラスにはありませんが、このメソッドは から継承されてC1います。これは を呼び出しself.gC3.g 定義されているため、 から継承されたメソッドをオーバーライドしますC1

于 2013-04-22T01:34:01.383 に答える