2012-09-28 28 views
3

此代碼:不帶參數的類方法產生類型錯誤

class testclass: 
    def __init__(self,x,y): 
     self.x = x 
     self.y = y 
     self.test() 

    def test(): 
     print('test') 

if __name__ == '__main__': 
    x = testclass(2,3) 

產量:

Error: 
TypeError:test() takes no argument(1 given) 

我打電話不帶任何參數的測試功能,爲什麼錯誤說,我已經給了一個?

回答

4

您將方法調用爲self.test()。您應該將其轉換爲test(self)以瞭解該函數定義中的「接收」方式。然而,您的test的定義僅僅是def test(),它沒有self去的地方,所以你得到你觀察到的錯誤。

爲什麼會出現這種情況?因爲Python只能在特定給定對象查找時查找屬性(並且查找屬性包括方法調用)。所以爲了讓這個方法做任何事情取決於它被調用的對象,它需要以某種方式接收該對象。接受它的機制是它的第一個參數。

有可能告訴Python,test根本不需要self,使用staticmethod裝飾器。在這種情況下,Python知道該方法不需要self,因此它不會嘗試將其添加爲第一個參數。所以,無論是test以下定義將解決您的問題:

def test(self): 
    print('test') 

OR:

@staticmethod 
def test(): 
    print('test') 

請注意,這只是與上調用對象的方法(它總是看起來像some_object.some_method(...))做。正常的函數調用(看起來像function(...))沒有任何「點左邊」,所以沒有self,所以它不會自動傳遞。

+0

我錯過了這個答案中** bound **和** unbound **方法之間的區別(在所有這些方法中直到現在)。這就是所有不同之處。當調用未綁定的方法時,你需要明確地傳遞'self',綁定的(通常情況下)它隱式地發生。 –

+0

@LukasGraf我將綁定方法視爲實現自我自動傳遞的機制,而不是核心概念。當然,他們遠遠超出了似乎適合這個問題的水平。實際上,從Python3中刪除了未綁定的方法是一個糟糕的想法(它將綁定的方法僅僅作爲記憶'self'以便將其傳遞給函數的機制),而Python的Python語法則提示Python3。 – Ben

6

通行證selftest方法:

def test(self): 
    print('test') 

您需要這樣做因爲Python明確傳遞參數指的是實例化的對象作爲第一個參數。即使該方法沒有參數(因爲指定的錯誤),它也不應該被省略。

+0

這僅適用於類功能嗎? – user1050619

+0

@ user1050619我還沒有聽說過任何其他的Python自動參數傳遞,但我可能是錯的。 –

+2

有一些標準的裝飾器'@ classmethod'和'@ staticmethod',它們可以將作爲第一個參數傳遞給(或不傳遞給)方法的內容進行修改。 – mgilson

1

Python總是將實例作爲實例方法的第一個參數傳遞,這意味着有時候關於參數個數的錯誤消息似乎被忽略。

class testclass: 
    def __init__(self,x,y): 
     self.x = x 
     self.y = y 
     self.test() 

    def test(self):   ## instance method 
     print('test', self) 

if __name__ == '__main__': 
    x = testclass(2,3) 

如果您不需要訪問類或實例,您可以使用一個靜態方法如下圖所示

class testclass: 
    def __init__(self,x,y): 
     self.x = x 
     self.y = y 
     self.test() 

    @staticmethod 
    def test(): 
     print('test') 

if __name__ == '__main__': 
    x = testclass(2,3) 

一類方法是類似的,如果你需要訪問class,但不是實例

class testclass: 
    def __init__(self,x,y): 
     self.x = x 
     self.y = y 
     self.test() 

    @classmethod 
    def test(cls): 
     print('test', cls) 

if __name__ == '__main__': 
    x = testclass(2,3) 
相關問題