简体   繁体   English

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

[英]Python - unpacking kwargs in local function call

I would like to pass a dictionary : 我想通过一dictionary

items = {"artist": "Radiohead", "track": "Karma Police"}

as a parameter to this function : 作为此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)

where last.get_track("Radiohead", "Karma Police") is the correct way of calling the local function . last.get_track("Radiohead", "Karma Police")是调用本地function的正确方法。

and then call it like this: 然后像这样调用它:

lastfm_similar_tracks(items)

I'm getting this error: 我收到这个错误:

TypeError: lastfm_similar_tracks() takes exactly 0 arguments (1 given)

how should I correct this? 我该怎么纠正这个?

Basically, **kwargs in function definition means named arguments should not be unpacked to variables. 基本上,函数定义中的** kwargs意味着命名参数不应该解包为变量。

To call some function with dictionary of arguments, these still need to be represented as named parameters. 要使用参数字典调用某些函数,这些函数仍需要表示为命名参数。 Else python "considers" supplied argument to be positional 其他python“考虑”提供的参数是位置的

Thus, you should call you function as: 因此,您应该将您的功能称为:

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

A few items of confusion: 一些混乱的事项:

You are passing the dictionary items as a parameter without the double star. 您将字典items作为参数传递,而不是双星。 This means that items is treated as the first positional argument, whereas your function only has **kwargs defined. 这意味着将items视为第一个位置参数,而您的函数仅定义了**kwargs

Here's a simple function: 这是一个简单的功能:

>>> def f(**kwargs):
...     print (kwargs)

Let's pass it items : 让我们传递它的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

Oops: no positional arguments are allowed. 糟糕:不允许使用位置参数。 You need to use the double star so that it will print: 您需要使用双星,以便打印:

>>> f(**items)
{'artist': 'Radiohead', 'track': 'Karma Police'}

This leads us to the next issue: kwargs inside the function is a dictionary , so you can't just pass it to last.get_track , which has two positional arguments according to your example. 这引出了我们下一个问题:函数内部的kwargs是一个字典 ,所以你不能只将它传递给last.get_track ,它根据你的例子有两个位置参数。 Assuming that order matters (it almost certainly does), you need to get the correct values from the dictionary to be passed: 假设顺序很重要(几乎可以肯定),你需要从字典中获取正确的值来传递:

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

First problem: you need to pass items in like this: 第一个问题:您需要像这样传递items

lastfm_similar_tracks(**items)

Second problem, inside lastfm_similar_tracks , kwargs is a dictionary, in which the keys are of no particular order, therefore you cannot guarantee the order when passing into get_track . 第二个问题,在lastfm_similar_trackskwargs是一个字典,其中的键没有特定的顺序,因此在传入get_track时无法保证顺序。 The best that you can do is: 你能做的最好的事情是:

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

At this point, the code should work the way you intended. 此时,代码应该按照您的预期方式工作。 However, I question the use of **kwargs in lastfm_similar_tracks : do you really need to define it that way? 但是,我质疑在lastfm_similar_tracks使用**kwargs :你真的需要这样定义吗? How about: 怎么样:

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

Then you can call it like so: 然后你可以像这样调用它:

lastfm_similar_tracks(**items)

This way, you ensure that the caller must pass in artist and track or the function call will fail. 这样,您可以确保调用者必须传入artisttrack否则函数调用将失败。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM