TypeError:method()接受1个位置参数,但给出了2个


269

如果我有课...

class MyClass:

    def method(arg):
        print(arg)

...我用来创建对象的...

my_object = MyClass()

我这样称呼method("foo")...

>>> my_object.method("foo")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: method() takes exactly 1 positional argument (2 given)

...为什么当我只给出一个参数时,Python告诉我给它两个参数?


该信息有多种原因。这里的具体原因是所有实例方法都期望有一个第一个arg,我们习惯将其称为self。因此,声明def method(arg):方法错误是应该的def method(self, arg):。当方法dispatch尝试针对它调用method(arg):并匹配两个参数self, arg时,您会收到该错误。
smci

Answers:


366

在Python中,这是:

my_object.method("foo")

...是语法糖,口译员在后台将其翻译为:

MyClass.method(my_object, "foo")

您可以看到,它确实有两个参数-从调用者的角度来看,只是第一个参数是隐式的。

这是因为大多数方法会对被调用的对象进行某些处理,因此需要某种方法在该方法内部引用该对象。按照惯例,第一个参数self在方法定义内调用:

class MyNewClass:

    def method(self, arg):
        print(self)
        print(arg)

如果您呼叫method("foo")的实例MyNewClass,它会按预期运作:

>>> my_new_object = MyNewClass()
>>> my_new_object.method("foo")
<__main__.MyNewClass object at 0x29045d0>
foo

有时(但不经常),您实际上不在乎您的方法所绑定的对象,在这种情况下,您可以使用内置函数来修饰该方法,staticmethod()例如:

class MyOtherClass:

    @staticmethod
    def method(arg):
        print(arg)

...在这种情况下,您无需self在方法定义中添加参数,它仍然有效:

>>> my_other_object = MyOtherClass()
>>> my_other_object.method("foo")
foo

99
简而言之:self在方法中添加第一个参数即可解决该问题。
amoebe

@amoebe-我的人类型
Carlos

21

遇到此类错误时要考虑的其他事项:

我遇到了这个错误消息,发现这篇文章很有帮助。事实证明,我重写了__init__()存在对象继承的位置。

继承的示例相当长,因此我将跳到一个不使用继承的更简单的示例:

class MyBadInitClass:
    def ___init__(self, name):
        self.name = name

    def name_foo(self, arg):
        print(self)
        print(arg)
        print("My name is", self.name)


class MyNewClass:
    def new_foo(self, arg):
        print(self)
        print(arg)


my_new_object = MyNewClass()
my_new_object.new_foo("NewFoo")
my_bad_init_object = MyBadInitClass(name="Test Name")
my_bad_init_object.name_foo("name foo")

结果是:

<__main__.MyNewClass object at 0x033C48D0>
NewFoo
Traceback (most recent call last):
  File "C:/Users/Orange/PycharmProjects/Chapter9/bad_init_example.py", line 41, in <module>
    my_bad_init_object = MyBadInitClass(name="Test Name")
TypeError: object() takes no parameters

PyCharm没有抓住这种错别字。Notepad ++也没有(其他编辑器/ IDE也可能)。

当然,这是一个“不带任何参数”的TypeError,与期望得到一个的“得到两个”没有太大区别,就Python中的对象初始化而言。

解决主题:在语法上正确的情况下将使用重载初始化程序,但在语法上正确的情况下将被使用,而是使用内置初始化程序。该对象不会期望/处理此问题,并且会引发错误。

如果出现sytax错误:修复很简单,只需编辑自定义init语句即可:

def __init__(self, name):
    self.name = name

1
这里没有SyntaxError。该代码在语法上是正确的;它只是正确定义了一个名为的方法___init__,而不是特殊方法,该方法永远没人会调用__init__。这就是为什么未检测到错误的原因,因为没有一个要检测的错误。
abarnert

14

简单来说。

在Python中,您应该将self参数作为第一个参数添加到类中所有已定义的方法中:

class MyClass:
  def method(self, arg):
    print(arg)

然后,您可以根据自己的直觉使用您的方法:

>>> my_object = MyClass()
>>> my_object.method("foo")
foo

这应该可以解决您的问题:)

为了更好地理解,您还可以阅读以下问题的答案:自我的目的是什么?


2
这个答案有什么问题?为什么有人给她一个负面点?毕竟,它是对问题的答案,与其他答案相比,它的简单性使其与众不同,这对于某些正在寻找答案的人而言可能很重要。是不是
simhumileco

10

Python的新手**,以错误的方式使用Python的功能时遇到了这个问题。尝试从某处调用此定义:

def create_properties_frame(self, parent, **kwargs):

使用没有双星的通话会导致问题:

self.create_properties_frame(frame, kw_gsp)

TypeError:create_properties_frame()接受2个位置参数,但给出了3个

解决方案是**在参数中添加:

self.create_properties_frame(frame, **kw_gsp)

1
来自JavaScript,我希望能够传递列表或字典作为参数。但是似乎这不是Python的工作方式:您必须使用*或**破坏列表,后者用于关键字参数列表。
有点脑子的

1
@LittleBrain:是的,如果希望将它们视为函数内的列表(/ dict),则可以传递列表(或字典)。但是,如果您希望解压缩它们的各个值并与函数中的args(/ kwargs)匹配,则需要使用*args(/ **kwargs)语法。
smci

9

当您未指定参数No __init__()或任何其他寻找方法时,就会发生这种情况。

例如:

class Dog:
    def __init__(self):
        print("IN INIT METHOD")

    def __unicode__(self,):
        print("IN UNICODE METHOD")

    def __str__(self):
        print("IN STR METHOD")

obj=Dog("JIMMY",1,2,3,"WOOF")

当您运行上述程序时,它给您这样的错误:

TypeError:__init __()接受1个位置参数,但给出了6个

我们如何摆脱这件事?

只需传递参数,__init__()寻找什么方法

class Dog:
    def __init__(self, dogname, dob_d, dob_m, dob_y, dogSpeakText):
        self.name_of_dog = dogname
        self.date_of_birth = dob_d
        self.month_of_birth = dob_m
        self.year_of_birth = dob_y
        self.sound_it_make = dogSpeakText

    def __unicode__(self, ):
        print("IN UNICODE METHOD")

    def __str__(self):
        print("IN STR METHOD")


obj = Dog("JIMMY", 1, 2, 3, "WOOF")
print(id(obj))

1

您实际上应该创建一个类:

class accum:
    def __init__(self):
        self.acc = 0
    def accumulator(self, var2add, end):
        if not end:
            self.acc+=var2add
    return self.acc

0

就我而言,我忘记添加 ()

我正在这样调用方法

obj = className.myMethod

但是应该是这样

obj = className.myMethod()

-1

cls参数传递到@classmethod以解决此问题。

@classmethod
def test(cls):
    return ''
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.