Метод класса генерирует "TypeError:... получил несколько значений для аргумента ключевого слова..."
Если я определяю метод класса с аргументом ключевого слова таким образом:
class foo(object):
def foodo(thing=None, thong='not underwear'):
print thing if thing else "nothing"
print 'a thong is',thong
вызов метода генерирует TypeError
:
myfoo = foo()
myfoo.foodo(thing="something")
...
TypeError: foodo() got multiple values for keyword argument 'thing'
Что происходит?
Ответы
Ответ 1
Проблема в том, что первый аргумент, переданный методам класса в python, всегда является копией экземпляра класса, на который вызывается метод, обычно помеченного self
. Если класс объявлен таким образом:
class foo(object):
def foodo(self, thing=None, thong='not underwear'):
print thing if thing else "nothing"
print 'a thong is',thong
он ведет себя так, как ожидалось.
Объяснение:
Без self
в качестве первого параметра, когда myfoo.foodo(thing="something")
выполняется, метод foodo
вызывается с аргументами (myfoo, thing="something")
. Затем экземпляр myfoo
присваивается thing
(поскольку thing
- первый объявленный параметр), но python также пытается назначить "something"
на thing
, следовательно, Исключение.
Чтобы продемонстрировать, попробуйте запустить это с помощью исходного кода:
myfoo.foodo("something")
print
print myfoo
Вы будете выводить как:
<__main__.foo object at 0x321c290>
a thong is something
<__main__.foo object at 0x321c290>
Вы можете видеть, что "вещи" была назначена ссылка на экземпляр "myfoo" класса "foo". Этот раздел в документах объясняет, как аргументы функции работают немного больше.
Ответ 2
Спасибо за поучительные посты. Я просто хотел бы отметить, что если вы получаете "TypeError: foodo() получил несколько значений для аргумента ключевого слова" вещь ", может также быть, что вы ошибочно передаете" я "в качестве параметра, когда вызывая функцию (вероятно, потому, что вы скопировали строку из объявления класса - это общая ошибка, когда вы спешите).
Ответ 3
Это может быть очевидно, но это может помочь тому, кто никогда не видел его раньше. Это также случается для регулярных функций, если вы ошибочно назначаете параметр по позиции и явно по имени.
>>> def foodo(thing=None, thong='not underwear'):
... print thing if thing else "nothing"
... print 'a thong is',thong
...
>>> foodo('something', thing='everything')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: foodo() got multiple values for keyword argument 'thing'
Ответ 4
просто добавьте декоратор "staticmethod" в функцию и проблема исправлена.
class foo(object):
@staticmethod
def foodo(thing=None, thong='not underwear'):
print thing if thing else "nothing"
print 'a thong is',thong
Ответ 5
Я хочу добавить еще один ответ:
Это происходит, когда вы пытаетесь передать позиционный параметр с неправильным порядок позиции вместе с аргументом ключевого слова в вызывающей функции.
there is difference between parameter and argument
вы можете подробно прочитать здесь Аргументы и параметр в python
def hello(a,b=1, *args):
print(a, b, *args)
hello(1, 2, 3, 4,a=12)
поскольку мы имеем три параметра:
a - позиционный параметр
b = 1 - ключевое слово и параметр по умолчанию
* args - параметр переменной длины
поэтому мы сначала назначаем как позиционный параметр, означает, что мы должны предоставить значение позиционному аргументу в его порядке позиции, здесь задайте вопрос.
но мы передаем аргумент 1 в месте функции вызова, а затем мы также предоставляем значение a, рассматривая как аргумент ключевого слова.
теперь a имеют два значения:
one - это позиционное значение: a = 1
second - ключевое слово, которое равно a = 12
Решение
Мы должны изменить hello(1, 2, 3, 4,a=12)
на hello(1, 2, 3, 4,12)
поэтому теперь a получит только одно позиционное значение, которое равно 1, а b получит значение 2, а остальные значения получат * args (параметр переменной длины)
дополнительная информация
если мы хотим, чтобы * args должны получить 2,3,4, а a должен получить 1 и b должен получить 12
тогда мы можем сделать так:
def hello(a,*args,b=1):
pass
hello(1, 2, 3, 4,b=12)
Что-то еще:
def hello(a,*c,b=1,**kwargs):
print(b)
print(c)
print(a)
print(kwargs)
hello(1,2,1,2,8,9,c=12)
вывод:
1
(2, 1, 2, 8, 9)
1
{'c': 12}
Ответ 6
Также это может произойти в Django, если вы используете jquery ajax для url, который обращается к функции, которая не содержит параметр "запрос"
$.ajax({
url: '{{ url_to_myfunc }}',
});
def myfunc(foo, bar):
...
Ответ 7
Эта ошибка также может произойти, если вы передадите аргумент ключевого слова, для которого один из ключей аналогичен (имеет такое же строковое имя) для позиционного аргумента.
>>> class Foo():
... def bar(self, bar, **kwargs):
... print(bar)
...
>>> kwgs = {"bar":"Barred", "jokes":"Another key word argument"}
>>> myfoo = Foo()
>>> myfoo.bar("fire", **kwgs)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: bar() got multiple values for argument 'bar'
>>>
"огонь" был принят в аргумент "bar". И все же есть еще один аргумент "бар", присутствующий в kwargs.
Вам нужно будет удалить аргумент ключевого слова из kwargs, прежде чем передать его методу.