2012-09-28 27 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) 
相关问题