2013-04-22 16 views
5

誰かがこのサイトでこの全く同じ問題を抱えていましたが、答えは私が問題がある部分には関係しませんでした。
継承 - メソッド呼び出し継承の問題。 - Python

以下のクラス定義を考慮してください。 fメソッドが呼び出されたときに呼び出されるメソッドを検討するために、あなたがこの問題については

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() 

。したがって、例えば、obj1.f()が呼び出されたとき、C1gメソッドを呼び出すC1のメソッドfが呼び出されます。これは、フォーム

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

の「呼び出しリスト」として表現することができ、それぞれ、変数obj2_callsからobj2.f()のための「呼び出しリスト」を割り当て、ということにobj3.f()のための「呼び出しリスト」を割り当て、3つの代入文を書きます変数obj3_callsを呼び出し、の '呼び出しリスト'を変数obj4_callsに割り当てます。

私は最初の割り当てを理解する問題はない、それはobj2_calls = ['C2.f', 'C1.g']
ですが、私は次のものを把握しようとしている私の脳を障るています。私は、リストが['C1.f']であることはC3.fではないと思ったが、残念ながらそうではありません。

ちょうどクリアし、これは

+3

実際に何が起こっているのか把握するために、各関数にいくつかの 'print'ステートメントを追加します。 –

+0

C3.fと入力すると、C3のC3の部分を意味するc3.f <バインド解除されたメソッドC3.f>が表示されます。 – Greg

+0

こんにちは、私は正しい答えがあります。しかし、私はコードの理解よりもそれを得るためにもっと常識を使いました。 答えが のobj3_calls = ['C1.f'、 'C​​3.g']の理由を理解したいと思います。私はなぜ 'c3.g'が 'c1.f'の後に呼び出されるのか理解していません –

答えて

1

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

3

これは、クラスのメソッド解決順序(MRO)と関係があります。 (いくつかの有用な情報のためのhereを参照)

正しく述べたように、そこにはC3.f機能がないので、Pythonはfが定義されているMROに最初の基本クラスにfメソッドを検索します。この場合、それは(C1)です。今、その方法(C1.f)はself.g()を呼び出します。それ以来、もちろん、self.gコールC3.gはMROにおける最高g関数であるので、この場合selfにおいて、C3のインスタンスです。あなたはC1.gを得ることを保証したい場合は、明示的にそれを行う必要があると思います。また、二重アンダースコアの名前の符号化の話に素敵なリードインを作る

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

を。それは別の話題なので、たぶんlink to some useful documentationのままにすることをお勧めします。

+0

すごい、ありがとう、そしてみんな助けてくれてありがとう。今、私は分かる –