2012-03-27 49 views
1

在我的頭上纏繞一點點麻煩。我相信答案很簡單,但它一直在推動着我。TypeError:B2()只需要1個參數(給出0)...爲什麼這個函數被完全調用爲named或變量

在下面的代碼:

class f1(): 
    valnum=1 

    def A1(self): 
     self.valnum=5 
     print self.valnum 

    def B2(self): 
     self.valnum=10 
     print self.valnum 


    funlist=[A1,B2] 


x=f1 
x() 

x().A1() 
x().funlist[1]() 

A1()會如預期執行,但不B2()。最終,我想讓代碼從列表中調用一個隨機函數,但TypeError: B2() takes exactly 1 argument (0 given)一直在阻礙我。爲什麼這是最好的解決方案。

謝謝。

回答

3

x().funlist[1]()沒有按照你的想法去做。

funlist是一個類屬性。它包含對實例方法A1B1的引用,但實際上並未將它們與任何實例相關聯 - 它們被稱爲未綁定的方法。

當你調用該代碼時,你可能試圖說「在0123k上調用實例x中的第一個函數」。但它實際上做的是「調用與類x類相關的類屬性funlist中引用的函數」,這根本不是一回事。

現在,Python實際上並沒有在綁定方法和非綁定方法之間做出很大區別。您可以假冒通過傳遞實例作爲第一個參數綁定 - 所以這會工作:

x_instance = x() 
x_instance.funlist[1](x_instance) 
+1

事實上,'funlist'包含*功能*,而不是實例方法或結合的方法。在從類對象中檢索函數之前,函數不會成爲未綁定的方法,並且在創建funlist時類對象還不存在。 – 2012-03-27 10:52:15

+0

謝謝,這是一個有用的說明。 – 2012-03-27 11:02:37

+0

或者,將funlist的定義移動到'__init__'中並讓它獲取實例方法併成爲一個實例屬性。 – agf 2012-03-27 11:09:30

0
x().funlist[1] 

評估的方法B2,但不bind它的臨時對象x()x().B2會做:

>>> f1().B2 
<bound method f1.B2 of <__main__.f1 instance at 0x1cb4d40>> 
>>> f1().funlist[1] 
<function B2 at 0x1c3cb90> 

的解決方案是明確地傳遞了「self」對象的方法:

obj = f1() 
obj.funlist[1](obj)