Если я определяю метод класса с аргументом ключевого слова следующим образом:
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'
В чем дело?
python
class
python-2.7
methods
drevicko
источник
источник
self
лучше, чем неявноеthis
.Ответы:
Проблема в том, что первый аргумент, передаваемый методам класса в python, всегда является копией экземпляра класса, для которого вызывается метод, обычно помеченного
self
. Если класс объявлен так:он ведет себя так, как ожидалось.
Объяснение:
Без
self
первого параметра, когдаmyfoo.foodo(thing="something")
выполняется,foodo
метод вызывается с аргументами(myfoo, thing="something")
. Затем экземплярmyfoo
назначаетсяthing
(посколькуthing
это первый объявленный параметр), но python также пытается назначить"something"
егоthing
, следовательно, исключение.Для демонстрации попробуйте запустить это с исходным кодом:
Вы выведете примерно так:
Вы можете видеть, что 'thing' была назначена ссылка на экземпляр 'myfoo' класса 'foo'. В этом разделе документации немного подробнее объясняется, как работают аргументы функций.
источник
Спасибо за поучительные посты. Я просто хотел бы отметить, что если вы получаете сообщение «TypeError: foodo () имеет несколько значений для аргумента ключевого слова 'thing'», возможно также, что вы ошибочно передаете 'self' в качестве параметра, когда вызов функции (вероятно, потому, что вы скопировали строку из объявления класса - это обычная ошибка, когда кто-то спешит).
источник
@classmethod
, решение - использоватьsuper().function(...)
вместо<parentclass>.function(cls, ...)
.Это может быть очевидно, но может помочь тому, кто никогда этого раньше не видел. Это также происходит с обычными функциями, если вы ошибочно назначаете параметр по позиции и явно по имени.
источник
просто добавьте декоратор staticmethod к функции, и проблема будет исправлена
источник
myfoo.foodo(thing="something")
, thing = "something" будет назначен первому аргументу, а не неявному аргументу self.self
Хочу добавить еще один ответ:
there is difference between parameter and argument
вы можете подробно прочитать здесь Аргументы и Параметры в Pythonпоскольку у нас есть три параметра:
a - позиционный параметр
b = 1 - ключевое слово и параметр по умолчанию
* args - параметр переменной длины
поэтому мы сначала назначаем a как позиционный параметр, это означает, что мы должны предоставить значение позиционному аргументу в его порядке позиции, здесь порядок имеет значение. но мы передаем аргумент 1 вместо a в вызывающей функции, а затем мы также предоставляем значение a, рассматривая его как аргумент ключевого слова. теперь у a есть два значения:
один - позиционное значение: a = 1
второй - это ключевое слово, равное 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)
Нечто большее :
вывод :
источник
Эта ошибка также может произойти, если вы передаете аргумент ключевого слова, для которого один из ключей похож (имеет такое же строковое имя) на позиционный аргумент.
«огонь» был принят в аргумент «бар». И все же у kwargs есть еще один аргумент о «решетке».
Вам нужно будет удалить аргумент ключевого слова из kwargs, прежде чем передавать его методу.
источник
Также это может произойти в Django, если вы используете jquery ajax для URL-адреса, который обращается к функции, которая не содержит параметр запроса.
источник