【问题标题】:Interesting 'takes exactly 1 argument (2 given)' Python error有趣的“只需要 1 个参数(给定 2 个)”Python 错误
【发布时间】:2011-02-05 20:54:19
【问题描述】:

对于错误:

TypeError: takes exactly 1 argument (2 given)

使用以下类方法:

def extractAll(tag):
   ...

并调用它:

e.extractAll("th")

当我给它 1 个参数时,错误似乎很奇怪,该方法应该只接受 1 个参数,但它说我没有给它 1 个参数....我知道可以通过添加 @ 来解决问题987654324@ 进入方法原型,但我想知道错误背后的原因。

我是不是因为通过e.extractAll("th") 调用它的行为也传入self 作为参数?如果是这样,通过删除调用中的self,我是否会使其成为某种可以像Extractor.extractAll("th") 一样调用的类方法?

【问题讨论】:

  • 只需在函数参数前添加self:def extractAll(self, tag)

标签: python


【解决方案1】:

电话

e.extractAll("th")

对于一个常规方法extractAll()确实相当于

Extractor.extractAll(e, "th")

这两个调用在所有方面都被视为相同,包括您收到的错误消息。

如果您不需要将实例传递给方法,您可以使用staticmethod

@staticmethod
def extractAll(tag):
    ...

可以称为e.extractAll("th")。但我想知道如果您不需要访问任何实例,为什么这是一个类上的方法。

【讨论】:

  • 如果我需要访问类的字段,在类中使用这个方法是合理的吗?...
  • @funk-shun:是的,但是你需要classsmethod,而不是staticmethod。并且很多时候,我会用普通的方法来处理这种方法。
  • @user2533809:通常,classmethod 的第一个参数称为cls,因为它是类本身,而不是它的实例。
  • 感谢 Sven Marnach 提供的信息,所以:def extractAll(self, tag) 被称为:my_obj.extractAll(tag) | @classmethod def extractAll(cls, tag) 被称为:Extract.extractAll(tag)
【解决方案2】:

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

def Method(self, atributes..)

所以,我想你的 'e' 是某个类的实例,该类具有尝试执行的已实现方法并且有太多参数。

【讨论】:

    【解决方案3】:

    是的,当您调用 e.extractAll(foo) 时,Python 会将其转换为 extractAll(e, foo)

    来自http://docs.python.org/tutorial/classes.html

    方法的特别之处在于 该对象作为第一个传递 函数的参数。在我们的 例如,调用 x.f() 正是 相当于 MyClass.f(x)。在 一般,用列表调用方法 n 个参数的 等价于 调用对应的函数 使用创建的参数列表 通过插入方法的对象 在第一个参数之前

    添加了重点。

    【讨论】:

      【解决方案4】:

      总结(python中如何在类中定义方法的一些例子)

      #!/usr/bin/env python   # (if running from bash)
      
      class Class1(object):
      
          def A(self, arg1):
              print arg1
              # this method requires an instance of Class1   
              # can access self.variable_name, and other methods in Class1
      
          @classmethod
          def B(cls, arg1):
              cls.C(arg1)
              # can access methods B and C in Class1 
      
          @staticmethod
          def C(arg1):
              print arg1
              # can access methods B and C in Class1 
              # (i.e. via Class1.B(...) and Class1.C(...))
      

      例子

      my_obj=Class1()
      
      my_obj.A("1")
      # Class1.A("2") # TypeError: method A() must be called with Class1 instance
      
      my_obj.B("3")
      Class1.B("4")
      my_obj.C("5")
      Class1.C("6")`
      

      【讨论】:

        【解决方案5】:

        我得到它是因为通过 e.extractAll("th") 调用它的行为也将 self 作为参数传递了吗?

        是的,就是这样。如果您愿意,第一个参数是对象名称,e,您正在调用它。

        如果是这样,通过删除调用中的 self,我是否可以将其变成某种可以调用的类方法,例如 Extractor.extractAll("th")?

        不完全是。类方法需要 @classmethod 装饰器,并且接受 class 作为第一个参数(通常引用为 cls)。唯一一种根本没有自动参数的方法被称为静态方法,它也需要一个装饰器(不出所料,它是@staticmethod)。当需要引用类本身的操作时使用类方法:可能是实例化类的对象;当代码在逻辑上属于类时使用静态方法,但不需要访问类或实例。

        但是,可以通过引用您描述的类名来调用静态方法和类方法:Extractor.extractAll("th")

        【讨论】:

        • 两者在共同的、编写良好的python代码中也比较少见。如果你认为你需要立即使用它们,我建议你重新考虑它是否需要在一个类中。也许您正在尝试使用 python 编写 Java。
        • 我有点喜欢使用 classmethod 作为工厂方法:它明确了正在创建的对象类型。
        【解决方案6】:

        尝试使用:

        def extractAll(self,tag):
        

        关注自己

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2018-03-29
          • 2010-11-11
          • 2012-03-07
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多