#python #keyword-argument
#python #ключевое слово-аргумент
Вопрос:
Я хотел бы передать dictionary
:
items = {"artist": "Radiohead", "track": "Karma Police"}
в качестве параметра для этого function
:
def lastfm_similar_tracks(**kwargs):
result = last.get_track(kwargs)
st = dict(str(item[0]).split(" - ") for item in result.get_similar())
print (st)
где last.get_track("Radiohead", "Karma Police")
— правильный способ вызова локальной function
.
а затем вызовите это следующим образом:
lastfm_similar_tracks(items)
Я получаю эту ошибку:
TypeError: lastfm_similar_tracks() takes exactly 0 arguments (1 given)
как я должен это исправить?
Ответ №1:
Несколько элементов путаницы:
Вы передаете словарь items
в качестве параметра без двойной звездочки. Это означает, что items
рассматривается как первый позиционный аргумент, тогда как ваша функция только **kwargs
определила.
Вот простая функция:
>>> def f(**kwargs):
... print (kwargs)
Давайте передадим это items
:
>>> items = {"artist": "Radiohead", "track": "Karma Police"}
>>> f(items)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: f() takes 0 positional arguments but 1 was given
Упс: не допускаются позиционные аргументы. Вам нужно использовать двойную звездочку, чтобы она печатала:
>>> f(**items)
{'artist': 'Radiohead', 'track': 'Karma Police'}
Это приводит нас к следующей проблеме: kwargs
внутри функции находится словарь, поэтому вы не можете просто передать его last.get_track
, который имеет два позиционных аргумента в соответствии с вашим примером. Предполагая, что порядок имеет значение (это почти наверняка имеет значение), вам нужно получить правильные значения из передаваемого словаря:
result = last.get_track(kwargs['artist'], kwargs['track'])
Ответ №2:
Первая проблема: вам нужно передать items
вот так:
lastfm_similar_tracks(**items)
Вторая проблема, внутренняя lastfm_similar_tracks
, kwargs
— это словарь, в котором ключи не имеют определенного порядка, поэтому вы не можете гарантировать порядок при передаче в get_track
. Лучшее, что вы можете сделать, это:
result = last.get_track(kwargs['artist'], kwargs['track'])
На этом этапе код должен работать так, как вы задумали. Однако я сомневаюсь в использовании **kwargs
in lastfm_similar_tracks
: вам действительно нужно определять это таким образом? Как насчет:
def lastfm_similar_tracks(artist, track, **kwargs):
result = last.get_track(artist, track)
# The rest of your code here
Тогда вы можете назвать это следующим образом:
lastfm_similar_tracks(**items)
Таким образом, вы гарантируете, что вызывающий должен передать artist
и track
, иначе вызов функции завершится неудачей.
Ответ №3:
По сути, ** kwargs в определении функции означает, что именованные аргументы не должны распаковываться в переменные.
Чтобы вызвать некоторую функцию со словарем аргументов, они все равно должны быть представлены в виде именованных параметров. Иначе python «считает» предоставленный аргумент позиционным
Таким образом, вы должны вызывать свою функцию как:
items = {"artist": "Radiohead", "track": "Karma Police"}
lastfm_similar_tracks(**items)
Комментарии:
1. Обратите внимание, что это все равно вызовет ошибку, потому что он передает
kwargs
словарь вlast.get_track
2. @agg3l Я пробовал это. это дает мне
TypeError: get_track() takes exactly 3 arguments (2 given)
3. @brianpck Хороший момент, я пропустил эту ошибку в блоке примера кода