Python - 在本地函数调用中解包kwargs

17
我想传递一个字典:

我希望传递一个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()需要0个参数,但给出了1个
我该怎么改正呢?
3个回答

10

有几个让人困惑的地方:

你将字典 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'])

8
第一个问题:你需要像这样传递items
lastfm_similar_tracks(**items)

第二个问题,在lastfm_similar_tracks内部,kwargs是一个字典,其中的键没有特定的顺序,因此在传入get_track时不能保证顺序。你所能做的最好办法是:

result = last.get_track(kwargs['artist'], kwargs['track'])

此时,代码应该按照您的意愿正常工作。然而,我对lastfm_similar_tracks中使用**kwargs的方法表示怀疑:您真的需要这样定义吗?以下是我的建议:

def lastfm_similar_tracks(artist, track, **kwargs):
    result = last.get_track(artist, track)
    # The rest of your code here

然后,您可以这样调用它:
lastfm_similar_tracks(**items)

这样,您可以确保调用者必须传入artisttrack,否则函数调用将失败。

6

基本上,函数定义中的 **kwargs 表示命名参数不应该被解包为变量。

如果要使用参数字典调用某个函数,仍需要将其表示为命名参数。否则,Python "认为"提供的参数是位置参数。

因此,您应该这样调用函数:

items = {"artist": "Radiohead", "track": "Karma Police"}
lastfm_similar_tracks(**items)

请注意,这仍会导致错误,因为他正在将“kwargs”字典传递给“last.get_track”。 - brianpck
@agg3l,我尝试过了。这会给我一个TypeError: get_track()需要传入3个参数,但只传入了2个 - 8-Bit Borges
@brianpck 好的,你说得对,我在示例代码块中漏掉了这个错误。 - agg3l

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接