"получено несколько значений для аргумента ключевого слова" при использовании *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, но это, похоже, не так.

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

1 ответ:

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

args = ([],)
В этом кортеже есть одно значение-объект списка. Он применяется после трех других аргументов, переданных в get_strategy(), то есть в request. Питон видит, что вы зовете:
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