Python TypeError:method()接受1个位置参数,但提供了2个

Python TypeError:method()接受1个位置参数,但提供了2个,python,python-3.x,methods,arguments,self,Python,Python 3.x,Methods,Arguments,Self,如果我有课 class MyClass: def method(arg): print(arg) …我用它来创建一个对象 my_object = MyClass() …我在上面调用方法(“foo”)就像这样 >>> my_object.method("foo") Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError:

如果我有课

class MyClass:

    def method(arg):
        print(arg)
…我用它来创建一个对象

my_object = MyClass()
…我在上面调用
方法(“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)
>>我的对象方法(“foo”)
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
TypeError:method()正好接受1个位置参数(给定2个)
…为什么Python告诉我我给了它两个参数,而我只给了一个

my_object.method("foo")
…是,口译员在幕后将其翻译为:

MyClass.method(my_object, "foo")
…正如你所看到的,它确实有两个参数——从调用方的角度来看,第一个参数是隐式的

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

class MyNewClass:

    def method(self, arg):
        print(self)
        print(arg)
如果在
MyNewClass
的实例上调用
方法(“foo”)
,它将按预期工作:

>>> my_new_object = MyNewClass()
>>> my_new_object.method("foo")
<__main__.MyNewClass object at 0x29045d0>
foo
…在这种情况下,您不需要向方法定义中添加
self
参数,它仍然有效:

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

<>当遇到这种类型的错误时要考虑的其他事项:

我遇到了这个错误消息,发现这个帖子很有帮助。事实证明,在我的例子中,我覆盖了一个
\uuuu init\uuuu()
,其中存在对象继承

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

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

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

例如:

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:\uuuu init\uuuuuu()接受1个位置参数,但给出了6个

我们怎样才能摆脱这件事

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

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
以解决此问题

@classmethod
def test(cls):
    return ''

简单地说。

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

class MyClass:
  def method(self, arg):
    print(arg)
然后你可以根据你的直觉使用你的方法:

>>> my_object = MyClass()
>>> my_object.method("foo")
foo
这将解决您的问题:)


为了更好地理解,您还可以阅读这个问题的答案:

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)

您应该实际创建一个类:

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

在我的例子中,我忘记添加
()

我是这样调用这个方法的

obj = className.myMethod
obj = className.myMethod()
但应该是这样的

obj = className.myMethod
obj = className.myMethod()

正如其他答案中提到的,当您使用实例方法时,需要将
self
作为第一个参数传递,这就是错误的来源

除此之外,重要的是要了解只有实例方法将
self
作为引用实例的第一个参数

如果方法是静态的,则不传递
self
,而是传递
cls
参数(或
class

请参见下面的示例

class City:

   country = "USA" # This is a class level attribute which will be shared across all instances  (and not created PER instance)

   def __init__(self, name, location, population):
       self.name       = name
       self.location   = location
       self.population = population
 
   # This is an instance method which takes self as the first argument to refer to the instance 
   def print_population(self, some_nice_sentence_prefix):
       print(some_nice_sentence_prefix +" In " +self.name + " lives " +self.population + " people!")

   # This is a static (class) method which is marked with the @classmethod attribute
   # All class methods must take a class argument as first param. The convention is to name is "cls" but class_ is also ok
   @classmethod
   def change_country(cls, new_country):
       cls.country = new_country

一些测试只是为了让事情更清楚:

# Populate objects
city1 = City("New York",    "East", "18,804,000")
city2 = City("Los Angeles", "West", "10,118,800")

#1) Use the instance method: No need to pass "self" - it is passed as the city1 instance
city1.print_population("Did You Know?") # Prints: Did You Know? In New York lives 18,804,000 people!

#2.A) Use the static method in the object
city2.change_country("Canada")

#2.B) Will be reflected in all objects
print("city1.country=",city1.country) # Prints Canada
print("city2.country=",city2.country) # Prints Canada

我在睡眠不足时出现此错误,并使用
def
而不是
class
创建了一个类:

def MyClass():
    def __init__(self, x):
        self.x = x

a = MyClass(3)
-> TypeError: MyClass() takes 0 positional arguments but 1 was given


这个故事的寓意是:在睡眠不足的情况下编程是一场失败的战斗。

在您的例子中,在创建类对象时,请在定义对象的类型后不要包含括号

代码应该是

my_object = MyClass
不是,

之后,调用方法是相同的

my_object.method("foo")

简而言之:将
self
作为第一个参数添加到方法中可以解决问题。@amoebe-我的类型,或者在定义@staticmethod之前只添加@staticmethod。酷这里没有语法错误。代码语法正确;它只是正确地定义了一个名为
\uuuuuuu init\uuuu
的方法,没有人会调用它,而不是特殊的方法
\uuuuu init\uuu
。这就是为什么没有检测到错误,因为没有要检测的错误。这个答案怎么了?为什么有人给她一个否定的观点?毕竟,它是问题的答案,与其他答案相比,它的简单性是它的显著特点,这对于一些正在寻找答案的人来说可能很重要。不是吗?来自JavaScript,我希望能够将列表或字典作为参数传递。但是Python似乎不是这样工作的:您必须使用*或**对列表进行解构,后者是一个关键字参数列表。@LittleBrain:是的,如果您希望列表(或dict)在函数中被视为列表(/dict),您可以传递一个列表(或dict)。但是,如果您希望将其单个值解压并与函数中的args(/kwargs)匹配,则需要
*args
(/
**kwargs
)语法;这里的具体原因是,所有实例方法都需要一个第一个参数,我们可以自定义地将其称为
self
。因此声明
def方法(arg):
对于一个方法来说是错误的,它应该是
def方法(self,arg):
。当方法分派尝试调用
method(arg):
并将两个参数
self,arg
与之匹配时,您会得到该错误。我将从OOP开始,并坚持使用此示例。我将非常感谢帮助解决它类Catalogo:def uuu init_uuu(self):self.peliculas=[]def agregar(self,peliculas):self.peliculas.append(pelicula)def mostrar(self):对于self.peliculas中的pelicula:
my_object.method("foo")