有趣的Python错误“期望1个参数(给了2个)”

61 投票
6 回答
122157 浏览
提问于 2025-04-16 11:18

关于这个错误:

TypeError: takes exactly 1 argument (2 given)

有一个这样的类方法:

def extractAll(tag):
   ...

然后我这样调用它:

e.extractAll("th")

这个错误看起来很奇怪,因为我只给了一个参数,而这个方法应该只需要一个参数,但它却说我没有给一个参数……我知道可以通过在方法定义里加上 self 来解决这个问题,但我想知道这个错误的原因。

我是不是因为通过 e.extractAll("th") 调用它时,self 也作为一个参数传进去了?如果是这样的话,如果我在调用时去掉 self,是不是就把它变成了一个可以像 Extractor.extractAll("th") 这样调用的类方法?

6 个回答

9

我是不是因为通过 e.extractAll("th") 调用它时,也把 self 作为参数传进去了?

没错,就是这个意思。如果你愿意,可以把第一个参数看作是你用来调用它的对象名,也就是 e

那么,如果我在调用时去掉 self,是否就能把它变成一种可以像 Extractor.extractAll("th") 这样调用的类方法?

不完全是。类方法需要用 @classmethod 装饰器,并且这个装饰器会把类本身作为第一个参数(通常用 cls 来表示)。唯一一种完全不自动传递参数的方法叫做静态方法,它也需要一个装饰器(没错,就是 @staticmethod)。类方法用于需要引用类本身的操作,比如创建类的实例;而静态方法则是逻辑上属于类的代码,但不需要访问类或实例。

不过,是的,静态方法和类方法都可以通过类名来调用,正如你所描述的那样:Extractor.extractAll("th")

28

如果一个非静态的方法是某个类的成员,你需要这样定义它:

def Method(self, atributes..)

所以,我猜你的'e'是某个类的实例,这个类里有一个方法,它试图执行,但传入的参数太多了。

82

这个调用

e.extractAll("th")

对于一个普通的方法 extractAll() 来说,实际上和下面这个调用是一样的

Extractor.extractAll(e, "th")

这两个调用在各个方面都是一样的,包括你收到的错误信息。

如果你不需要把实例传给一个方法,你 可以 使用 staticmethod

@staticmethod
def extractAll(tag):
    ...

这样可以像 e.extractAll("th") 这样调用。但是我在想,如果你根本不需要访问任何实例,那这个方法为什么要放在类里面呢?

撰写回答