关于python:TypeError:method()需要1个位置参数,但是给出了2个

TypeError: method() takes 1 positional argument but 2 were given

如果我有课…

1
2
3
4
class MyClass:

    def method(arg):
        print(arg)

…我用来创建一个对象…

1
my_object = MyClass()

…在这上面我这样称呼method("foo")

1
2
3
4
>>> 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告诉我我给出了两个参数?


在python中,这是:

1
my_object.method("foo")

…是句法上的糖分,解释人员在幕后将其翻译成:

1
MyClass.method(my_object,"foo")

…正如您所看到的,它确实有两个参数——从调用者的角度来看,第一个参数是隐式的。

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

1
2
3
4
5
class MyNewClass:

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

如果您在MyNewClass的实例上调用method("foo"),它将按预期工作:

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

偶尔(但不是经常),你真的不关心你的方法所绑定到的对象,在这种情况下,你可以用内置的staticmethod()函数来修饰方法,这样说:

1
2
3
4
5
class MyOtherClass:

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

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

1
2
3
>>> my_other_object = MyOtherClass()
>>> my_other_object.method("foo")
foo


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

我偶然发现了这个错误消息,发现这个帖子很有用。在我的例子中,我重写了一个init(),其中有对象继承。

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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")

结果是:

1
2
3
4
5
6
<__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也不例外)。

当然,这是一个"不带参数"的类型错误,在Python中的对象初始化方面,它与预期的"有两个"没有太大的不同。

解决主题:如果语法正确,将使用重载初始值设定项,但如果不正确,将忽略它,而改用内置项。对象不会期望/处理此问题,并引发错误。

在Sytax错误的情况下:修复很简单,只需编辑自定义init语句:

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


当您没有指定init()或任何其他方法要查找的参数的数目时,就会发生这种情况。

例如

1
2
3
4
5
6
7
8
9
10
11
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的错误:uuinit_uu()接受1个位置参数,但给出了6个

我们怎样才能摆脱这件事?

只需传递参数,init()方法要查找的内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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))

cls参数传递到@classmethod中,解决这个问题。

1
2
3
@classmethod
def test(cls):
    return ''