4

I am trying to understand the difference between *args and **args in function definition in python. In the below example, *args works to pack into a tuple and calculate the sum.

>>> def add(*l):
... sum = 0
... for i in l:
... sum+=i
... return sum ...
>>> add(1,2,3)
6
>>> l = [1,2,3]
>>>add(*l)
6

for ** args,

>>> def f(**args):
...     print(args)
... 
>>> f()
{}
>>> f(de="Germnan",en="English",fr="French")
{'fr': 'French', 'de': 'Germnan', 'en': 'English'}
>>> 

I see that it takes parameters and turns into a dictionary. But I do not understand the utility or other things that could be helpful when using ** args. In fact, I dont know what *args and **args are called(vararg and ?)

Thanks

eagertoLearn
  • 9,772
  • 23
  • 80
  • 122
  • For "I dont know what *args and **args are called": That's because there aren't really official names. The terms "var-positional parameter" and "var-keyword parameter" are used in a few places in the docs and in the source; PEP3102 uses "vararg parameter slot" and "keyword dictionary parameter slot". But those don't really trip off the tongue. People usually say something like "varags parameter" and "kwargs parameter". – abarnert Sep 12 '13 at 01:03
  • 2
    I strongly recommend reading the [official tutorial](http://docs.python.org/2/tutorial/). For this question in particular, it has a whole section on [(somewhat) advanced function definitions](http://docs.python.org/2/tutorial/controlflow.html#more-on-defining-functions). But really, the whole tutorial is quite good. – John Y Sep 12 '13 at 01:04
  • Also, "I see that it takes parameters and turns into a dictionary" is wrong. It takes (keyword) _arguments_ and turns them into a dictionary, which is passed to the single kwargs parameter. You can often get away with being loose about arguments and parameters, but in this area you're going to confuse yourself. [This blog post](http://stupidpythonideas.blogspot.com/2013/08/arguments-and-parameters.html) tries to explain it (and links to better explanations). – abarnert Sep 12 '13 at 01:08
  • Finally, do you understand the point of keyword arguments in the first place? Because that's 90% of the answer to this question. `*args` gets all the excess positional arguments; `**kwargs` gets all the excess keyword arguments. – abarnert Sep 12 '13 at 01:12

1 Answers1

10

When you use two asterisks you usually call them **kwargs for keyword arguments. They are extremely helpful for passing parameters from function to function in a large program.

A nice thing about keyword arguments is that it is really easy to modify your code. Let's say that in the below example you also decided that parameter cube is also relevant. The only thing you would need to do is add one if statement in my_func_2, and you would not need to add a parameter to every function that is calling my_func_2, (as long as that functions has **kwargs).

Here is a simple rather silly example, but I hope it helps:

def my_func_1(x, **kwargs):
    if kwargs.get('plus_3'):
        return my_func_2(x, **kwargs) + 3
    return my_func_2(x, **kwargs)

def my_func_2(x, **kwargs):
    #Imagine that the function did more work
    if kwargs.get('square'):
        return x ** 2
    # If you decided to add cube as a parameter 
    # you only need to change the code here:
    if kwargs.get('cube'):
        return x ** 3
    return x

Demo:

>>> my_func_1(5)
5
>>> my_func_1(5, square=True)
25
>>> my_func_1(5, plus_3=True, square=True)
28
>>> my_func_1(5, cube=True)
125
Akavall
  • 82,592
  • 51
  • 207
  • 251