ТипError: метод() принимает 1 позиционный аргумент, но 2 даны
Если у меня есть класс...
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 говорит мне, что я дал ему два аргумента, когда я только дал один?
Ответы
Ответ 1
В 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
Ответ 2
Что-то еще нужно учитывать при возникновении такого типа ошибки:
Я столкнулся с этим сообщением об ошибке и нашел это сообщение полезным. Оказывается, в моем случае я переопределил 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
Ответ 3
Это происходит, когда вы не указываете число параметров, которое ищет __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__() takes 1 positional argument but 6 were given
Как мы можем избавиться от этой вещи?
Просто передайте параметры, что ищет метод __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))
Ответ 4
Новичок в Python, у меня была эта проблема, когда я неправильно использовал функцию Python **
. Попытка вызвать это определение откуда-то:
def create_properties_frame(self, parent, **kwargs):
проблема с вызовом без двойной звезды:
self.create_properties_frame(frame, kw_gsp)
TypeError: create_properties_frame() takes 2 positional arguments but 3 were given
Решение состоит в том, чтобы добавить ** к аргументу:
self.create_properties_frame(frame, **kw_gsp)
Ответ 5
Простыми словами.
В Python вы должны добавить аргумент self
в качестве первого аргумента для всех определенных методов в классах:
class MyClass:
def method(self, arg):
print(arg)
Тогда вы можете использовать свой метод в соответствии с вашей интуицией:
>>> my_object = MyClass()
>>> my_object.method("foo")
foo
Это должно решить вашу проблему :)
Для лучшего понимания вы также можете прочитать ответы на этот вопрос: какова цель самого себя?
Ответ 6
Передайте параметр cls
в @classmethod
чтобы решить эту проблему.
@classmethod
def test(cls):
return ''