2013-04-22 66 views
5

有人在這個網站上有這個完全相同的問題,但答案並沒有涉及到我有麻煩的部分。
繼承 - 方法調用繼承問題。 - Python

請考慮以下類定義。

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()時,將調用C1f方法,該方法調用C1g方法。這可以表示爲形式

['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'],但不幸的是它不是。

只是爲了澄清,這是功課

+3

爲每個函數添加一些'print'語句來找出真正發生的事情。 – 2013-04-22 01:19:33

+0

如果你輸入C3.f,你會看到c3.f ,這意味着它是類C3的一部分 – Greg 2013-04-22 01:25:31

+0

嗨,大家非常有幫助,使用print我有正確的答案。但是我比理解代碼更常用。 我還是想明白爲什麼答案是 obj3_calls = ['C1.f','C3.g']。'c1.f' – 2013-04-22 01:31:54

回答

1

obj3_calls爲['C1.f', 'C3.g']。正如您指出的那樣,該類中沒有C3.f,但是此方法從C1繼承。這一個依次調用self.g,並且因爲C3.g定義的,它將覆蓋從C1繼承的方法。

3

這與您班級的方法解析順序(MRO)有關。 (見here一些有用的信息)

正如你正確地指出,沒有C3.f功能,所以Python中查找f方法上最初的基類中已定義f的MRO。在這種情況下,即(C1)。現在,該方法(C1.f)稱爲self.g()。在這種情況下,selfC3的一個實例,因此當然,self.g調用C3.g,因爲這是MRO中的最高g函數。如果你想保證你得到C1.g,你需要明確地做到這一點:

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

這也使得一個很好的引入到談論雙下劃線名字改編。因爲這是一個單獨的主題,所以最好只留下link to some useful documentation

+0

太棒了,謝謝你,並感謝大家的幫助。我現在知道了 – 2013-04-22 01:39:59