Ошибка типа: функция (self, item, ** kwargs) принимает ровно 2 аргумента (задано 3)

#python #flask #keyword-argument

#python #flask #ключевое слово-аргумент

Вопрос:

У меня есть функция, которая помещает данные в базу данных, называется new_item() :

 def new_item(self, item, **optional):
  

После отправки веб-формы функция должна проверить ввод пользователя, а затем использовать эту функцию для ввода пользовательского ввода в базу данных (я использую Flask, имя функции add_item() ):

 Market.new_item([request.form['title'], 
                 session.get('user_id'), 
                 request.form['category']], 
                {'desc': request.form['desc'], 
                 'place': request.form['place'], 
                 'price': request.form['price'], 
                 'ono': ono})
  

Но я получаю эту ошибку:

 File X, line 99, in add_item
'ono': ono})
TypeError: new_item() takes exactly 2 arguments (3 given)
  

Для отладки я печатаю это утверждение прямо перед вызовом функции add_item . Вывод на консоль:

 ([u'iPhone 5', '791465667539154', u'2'], 
 {'price': u'99', 'place': u'Bossental', 'ono': True, 'desc': u'My brand new iPhone'})
  

Я действительно не знаю, что не так. Я никогда **kwargs раньше не работал; это связано с проблемой?

Ответ №1:

Вы предоставляете функции три аргумента:

  1. Неявный self аргумент, Market ;
  2. Список, который будет item ; и
  3. Словарь, который вызывает проблему.

**optional это специальный аргумент, который объединяет все аргументы ключевого слова, которые еще не указаны, в словарь, доступный внутри функции как optional (по соглашению, это обычно вызывается kwargs ).

Быстрая демонстрация:

 >>> def demo(x, y=None, **kwargs):
    print 'x: {0}'.format(x)
    print 'y: {0}'.format(y)
    print 'kwargs: {0}'.format(kwargs)


>>> demo('foo', y='bar', z='baz')
x: foo # 'x' positional argument
y: bar # 'y' keyword argument
kwargs: {'z': 'baz'} # unspecified keyword arguments
  

Вы можете распаковать словарь в аргументы ключевого слова с помощью ** :

 >>> demo('foo', **{'y': 'bar', 'z': 'baz'})
x: foo
y: bar
kwargs: {'z': 'baz'}
  

Поэтому, если вы хотите передать содержимое словаря в **optional аргумент, вы можете использовать тот же синтаксис для распаковки словаря в аргументы ключевого слова:

 Market.new_item([request.form['title'], 
                 session.get('user_id'), 
                 request.form['category']], 
                **{'desc': request.form['desc'],
              # ^ note asterisks
                   'place': request.form['place'],
                   'price': request.form['price'],
                   'ono': ono })
  

Ответ №2:

 Market.new_item(
    [request.form['title'], session.get('user_id'), request.form['category']], 
    optional={
        'desc': request.form['desc'],
        'place': request.form['place'],
        'price': request.form['price'],
        'ono': ono 
    }
)
  

Ответ №3:

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

Эта ссылка содержит больше информации о аргументах ключевых слов

Возможно, вам нужно изменить свой код следующим образом. Тогда это сработало бы

 Market.new_item([request.form['title'], session.get('user_id'), request.form['category']], 
'desc' = request.form['desc'],
'place' = request.form['place'],
'price' = request.form['price'],
'ono' = ono)
  

Надеюсь, это поможет!