有趣的Python错误“期望1个参数(给了2个)”
关于这个错误:
TypeError: takes exactly 1 argument (2 given)
有一个这样的类方法:
def extractAll(tag):
...
然后我这样调用它:
e.extractAll("th")
这个错误看起来很奇怪,因为我只给了一个参数,而这个方法应该只需要一个参数,但它却说我没有给一个参数……我知道可以通过在方法定义里加上 self
来解决这个问题,但我想知道这个错误的原因。
我是不是因为通过 e.
extractAll("th") 调用它时,self
也作为一个参数传进去了?如果是这样的话,如果我在调用时去掉 self
,是不是就把它变成了一个可以像 Extractor.extractAll("th")
这样调用的类方法?
6 个回答
我是不是因为通过 e.extractAll("th") 调用它时,也把 self 作为参数传进去了?
没错,就是这个意思。如果你愿意,可以把第一个参数看作是你用来调用它的对象名,也就是 e
。
那么,如果我在调用时去掉 self,是否就能把它变成一种可以像 Extractor.extractAll("th") 这样调用的类方法?
不完全是。类方法需要用 @classmethod
装饰器,并且这个装饰器会把类本身作为第一个参数(通常用 cls
来表示)。唯一一种完全不自动传递参数的方法叫做静态方法,它也需要一个装饰器(没错,就是 @staticmethod
)。类方法用于需要引用类本身的操作,比如创建类的实例;而静态方法则是逻辑上属于类的代码,但不需要访问类或实例。
不过,是的,静态方法和类方法都可以通过类名来调用,正如你所描述的那样:Extractor.extractAll("th")
。
如果一个非静态的方法是某个类的成员,你需要这样定义它:
def Method(self, atributes..)
所以,我猜你的'e'是某个类的实例,这个类里有一个方法,它试图执行,但传入的参数太多了。
这个调用
e.extractAll("th")
对于一个普通的方法 extractAll()
来说,实际上和下面这个调用是一样的
Extractor.extractAll(e, "th")
这两个调用在各个方面都是一样的,包括你收到的错误信息。
如果你不需要把实例传给一个方法,你 可以 使用 staticmethod
:
@staticmethod
def extractAll(tag):
...
这样可以像 e.extractAll("th")
这样调用。但是我在想,如果你根本不需要访问任何实例,那这个方法为什么要放在类里面呢?