Метод класса генерирует «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'

Что происходит?

113 голосов | спросил drevicko 23 rdEurope/Moscowp30Europe/Moscow09bEurope/MoscowMon, 23 Sep 2013 04:08:45 +0400 2013, 04:08:45

7 ответов


0

Проблема в том, что первый аргумент, передаваемый методам класса в 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>

Вы можете видеть, что для 'thing' была назначена ссылка на экземпляр 'myfoo' класса 'foo'. В этом разделе документов объясняется, как аргументы функций работают немного больше.

ответил drevicko 23 rdEurope/Moscowp30Europe/Moscow09bEurope/MoscowMon, 23 Sep 2013 04:08:45 +0400 2013, 04:08:45
0

Спасибо за поучительные сообщения. Я просто хотел бы отметить, что если вы получаете "TypeError: foodo () получил несколько значений для ключевого аргумента" вещь "", возможно, вы ошибочно передаете "я" в качестве параметра, когда вызов функции (возможно, потому что вы скопировали строку из объявления класса - это обычная ошибка, когда вы спешите).

ответил joe_doe 25 J000000Friday14 2014, 00:27:57
0

Это может быть очевидно, но это может помочь кому-то, кто никогда не видел это раньше. Это также происходит с обычными функциями, если вы по ошибке назначаете параметр по позиции и явно по имени.

>>> 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'
ответил woot 5 AM00000060000005431 2015, 06:20:54
0

просто добавьте декоратор staticmethod в функцию, и проблема будет устранена

class foo(object):
    @staticmethod
    def foodo(thing=None, thong='not underwear'):
        print thing if thing else "nothing" 
        print 'a thong is',thong
ответил adi gunawan 24 thEurope/Moscowp30Europe/Moscow09bEurope/MoscowThu, 24 Sep 2015 14:47:41 +0300 2015, 14:47:41
0

Я хочу добавить еще один ответ:

  

Это происходит, когда вы пытаетесь передать позиционный параметр с неправильным   порядок позиции вместе с ключевым аргументом в вызывающей функции.

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 вместо функции in в вызывающей функции, а затем мы также предоставляем значение a, рассматривая его как аргумент ключевого слова. теперь есть два значения:

это позиционное значение: a = 1

секунда - это ключевое слово, которое равно = 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}
ответил Aaditya Ura 10 +03002016-10-10T14:56:22+03:00312016bEurope/MoscowMon, 10 Oct 2016 14:56:22 +0300 2016, 14:56:22
0

Эта ошибка также может произойти, если вы передаете аргумент ключевого слова, для которого один из ключей похож (имеет одинаковое имя строки), на позиционный аргумент.

>>> 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 есть еще один аргумент «bar».

Вы должны будете удалить аргумент ключевого слова из kwargs перед передачей его методу.

ответил unlockme 30 PM00000010000004531 2017, 13:33:45
0

Также это может произойти в Django, если вы используете jquery ajax для ссылки, обращающейся к функции, которая не содержит параметр 'request'

$.ajax({
  url: '{{ url_to_myfunc }}',
});


def myfunc(foo, bar):
    ...
ответил lukeaus 31 Maypm16 2016, 12:36:58

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132