получил несколько значений аргумента ключевого слова при использовании * args, ** kwargs в функции python

При передаче именованного параметра request через **kwargs я получаю сообщение об ошибке:

Traceback (most recent call last):
  File "testKwargs.py", line 9, in <module>
    load_strategy(request="myReq", backend="myBackend", redirect_uri=None, *args, **kwargs)
  File "testKwargs.py", line 5, in load_strategy
    get_strategy("backends", "strategy", "storage", *args, **kwargs)
TypeError: get_strategy() got multiple values for keyword argument 'request'

Код в testKwargs.py ниже-

def get_strategy(backends, strategy, storage, request=None, backend=None, *args, **kwargs):
    print request

def load_strategy(*args, **kwargs):
    get_strategy("backends", "strategy", "storage", *args, **kwargs)

args = ([],)
kwargs = {"acess_token":"myAccToken", "id":"myId"}
load_strategy(request="myReq", backend="myBackend", redirect_uri=None, *args, **kwargs)

Я ожидал, что будет одна пара ключ-значение для ключа request в **kwargs из load_strategy, которая будет передана параметру request в get_stragegy, но, похоже, это не так.

Я пытаюсь понять, чего мне здесь не хватает.


person Devang    schedule 15.12.2013    source источник
comment
Если вы имеете в виду, что get_strategy() не является методом класса, то да, я уверен, что это не так. Фактически, небольшого фрагмента кода в вопросе достаточно, чтобы воспроизвести проблему.   -  person Devang    schedule 16.12.2013
comment
Да, я увидел, что вы действительно предоставляете полный SSCCE, а затем увидел ошибку.   -  person Martijn Pieters    schedule 16.12.2013


Ответы (1)


Вы передаете дополнительный позиционный аргумент:

args = ([],)

В этом кортеже есть одно значение — объект списка. Он применяется после того, как остальные три аргумента переданы в get_strategy(), то есть в request. Python видит, как вы звоните:

get_strategy("backends", "strategy", "storage", [],
             request="myReq", backend="myBackend", redirect_uri=None, 
             acess_token="myAccToken", id="myId")

и 4 позиционных аргумента применяются к параметрам backends, strategy, storage и request соответственно.

Если вы хотели передать 3 позиционных аргумента, укажите args как пустой кортеж:

args = ()

и все работает просто отлично:

>>> def get_strategy(backends, strategy, storage, request=None, backend=None, *args, **kwargs):
...     print request
... 
>>> def load_strategy(*args, **kwargs):
...     get_strategy("backends", "strategy", "storage", *args, **kwargs)
... 
>>> args = ()
>>> kwargs = {"acess_token":"myAccToken", "id":"myId"}
>>> load_strategy(request="myReq", backend="myBackend", redirect_uri=None, *args, **kwargs)
myReq
person Martijn Pieters    schedule 15.12.2013