简体   繁体   中英

func(*tuple) 'scatters' tuples, but how does func(**dictionary) work?

Let's create a simple tuple, dictionary and function.

>>> tup = (7, 3)
>>> dic = {"kw1":7, "kw2":3}
>>> def pr(a, b):
...    print a, b

The following shows what * does before a tuple and dictionary as an argument.

>>> pr(tup)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: pr() takes exactly 2 arguments (1 given)

>>> pr(*tup)  
7 3   

>>> pr(*dic)
kw1 kw2

Now let's try ** before an argument.

>>> pr(**tup)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: pr() argument after ** must be a mapping, not tuple

Ok, it seems ** only works when a dictionary is used as an argument. So let's try it with a dictionary then.

>>> pr(**dic)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: pr() got an unexpected keyword argument 'kw1'

What? Can anybody show me an example of this last case that doesn't produce an error?

To add to the other answers, you can use *args and **kwargs to your function definition to support arbitrary arguments. This may make the code less explicit. But for debug purposes, flexibility and development speed this may make sense to adopt:

(The * / ** -notation in the function definition is like the "inverse" operation to the argument unpacking operation on function call.)

def foo(*args, **kwargs): 
    for v in args: 
        print v
    for v in kwargs: 
        print v, "->", kwargs[v]

dic = {"kw1":7, "kw2":3}

foo(dic)
# prints:
# {'kw1': 7, 'kw2': 3}

foo(**dic)
# prints:
# kw1 -> 7
# kw2 -> 3

some related links to the documentation:

The **dict notation means that your dictionary is turned into keyword arguments. If the function doesn't possess the necessary keyword, then it will return an error, as you experienced.

In your case, it would work if you defined your function as follows:

>>> def pr(kw1, kw2):
...    print kw1, kw2

Your pr function takes arguments a and b , not kw1 and kw2 .

>>> def pr(a, b):
...   print a, b
... 
>>> 
>>> d = {'a': 1, 'b':2}
>>> pr(**d)
1 2

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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