метод класса генерирует "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'
что происходит?
7 ответов:
проблема в том, что первый аргумент, передаваемый методам класса в 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". в этом разделе из документов объясняет, как аргументы функции работают немного больше.
Спасибо за поучительные посты. Я просто хотел бы отметить, что если вы получаете "TypeError: foodo() получил несколько значений для ключевого аргумента" thing", Это также может быть, что вы ошибочно передаете "self" в качестве параметра при вызове функции (вероятно, потому, что вы скопировали строку из объявления класса - это распространенная ошибка, когда кто-то спешит).
это может быть очевидно, но это может помочь тому, кто никогда не видел его раньше. Это также происходит для обычных функций, если вы ошибочно назначаете параметр по позиции и явно по имени.
>>> 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'
просто добавьте декоратор "staticmethod" в функцию, и проблема исправлена
class foo(object): @staticmethod def foodo(thing=None, thong='not underwear'): print thing if thing else "nothing" print 'a thong is',thong
Я хочу добавить еще один ответ :
это происходит, когда вы пытаетесь пройти позиционный параметр с неправильным порядок позиций вместе с аргументом ключевого слова в вызывающей функции.
there is difference between parameter and argument
вы можете прочитать подробно здесь Аргументы и параметры в pythondef hello(a,b=1, *args): print(a, b, *args) hello(1, 2, 3, 4,a=12)
так как у нас есть три параметра:
a-позиционный параметр
Б=1 ключевое слово и параметр по умолчанию
*args-параметр переменной длины
поэтому мы сначала назначаем как позиционный параметр, значит, мы должны предоставить значение позиционному аргументу в его порядке расположения, здесь порядок имеет значение. но мы передаем аргумент 1 в место A в вызывающей функции , а затем мы также предоставляем значение a, рассматривая как аргумент ключевого слова. теперь есть два значения :
одно позиционное значение: a=1
второе значение keyworded которое 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}
эта ошибка также может произойти, если вы передаете аргумент ключевого слова, для которого один из ключей похож (имеет такое же имя строки) на позиционный аргумент.
>>> 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 перед передачей его в метод.