What is the purpose and use of **kwargs?

648,383

Solution 1

You can use **kwargs to let your functions take an arbitrary number of keyword arguments ("kwargs" means "keyword arguments"):

>>> def print_keyword_args(**kwargs):
...     # kwargs is a dict of the keyword args passed to the function
...     for key, value in kwargs.iteritems():
...         print "%s = %s" % (key, value)
... 
>>> print_keyword_args(first_name="John", last_name="Doe")
first_name = John
last_name = Doe

You can also use the **kwargs syntax when calling functions by constructing a dictionary of keyword arguments and passing it to your function:

>>> kwargs = {'first_name': 'Bobby', 'last_name': 'Smith'}
>>> print_keyword_args(**kwargs)
first_name = Bobby
last_name = Smith

The Python Tutorial contains a good explanation of how it works, along with some nice examples.

Python 3 update

For Python 3, instead of iteritems(), use items()

Solution 2

Unpacking dictionaries

** unpacks dictionaries.

This

func(a=1, b=2, c=3)

is the same as

args = {'a': 1, 'b': 2, 'c':3}
func(**args)

It's useful if you have to construct parameters:

args = {'name': person.name}
if hasattr(person, "address"):
    args["address"] = person.address
func(**args)  # either expanded to func(name=person.name) or
              #                    func(name=person.name, address=person.address)

Packing parameters of a function

  • Use .items() instead of .iteritems() for python 3
def setstyle(**styles):
    for key, value in styles.iteritems():      # styles is a regular dictionary
        setattr(someobject, key, value)

This lets you use the function like this:

setstyle(color="red", bold=False)

Notes

  • kwargs is variable name used for keyword arguments, another variable name can be used. The important part is that it's a dictionary and it's unpacked with the double asterisk operator **.
  • Other iterables are unpacked with the single asterisk operator *
  • To prevent confusion, it's probably best to stick with the recognized variable names, kwargs and args, for dictionaries and other iterables respectively.

Resources

Solution 3

kwargs is just a dictionary that is added to the parameters.

A dictionary can contain key, value pairs. And that are the kwargs. Ok, this is how.

The what for is not so simple.

For example (very hypothetical) you have an interface that just calls other routines to do the job:

def myDo(what, where, why):
   if what == 'swim':
      doSwim(where, why)
   elif what == 'walk':
      doWalk(where, why)
   ...

Now you get a new method "drive":

elif what == 'drive':
   doDrive(where, why, vehicle)

But wait a minute, there is a new parameter "vehicle" -- you did not know it before. Now you must add it to the signature of the myDo-function.

Here you can throw kwargs into play -- you just add kwargs to the signature:

def myDo(what, where, why, **kwargs):
   if what == 'drive':
      doDrive(where, why, **kwargs)
   elif what == 'swim':
      doSwim(where, why, **kwargs)

This way you don't need to change the signature of your interface function every time some of your called routines might change.

This is just one nice example you could find kwargs helpful.

Solution 4

On the basis that a good sample is sometimes better than a long discourse I will write two functions using all python variable argument passing facilities (both positional and named arguments). You should easily be able to see what it does by yourself:

def f(a = 0, *args, **kwargs):
    print("Received by f(a, *args, **kwargs)")
    print("=> f(a=%s, args=%s, kwargs=%s" % (a, args, kwargs))
    print("Calling g(10, 11, 12, *args, d = 13, e = 14, **kwargs)")
    g(10, 11, 12, *args, d = 13, e = 14, **kwargs)

def g(f, g = 0, *args, **kwargs):
    print("Received by g(f, g = 0, *args, **kwargs)")
    print("=> g(f=%s, g=%s, args=%s, kwargs=%s)" % (f, g, args, kwargs))

print("Calling f(1, 2, 3, 4, b = 5, c = 6)")
f(1, 2, 3, 4, b = 5, c = 6)

And here is the output:

Calling f(1, 2, 3, 4, b = 5, c = 6)
Received by f(a, *args, **kwargs) 
=> f(a=1, args=(2, 3, 4), kwargs={'c': 6, 'b': 5}
Calling g(10, 11, 12, *args, d = 13, e = 14, **kwargs)
Received by g(f, g = 0, *args, **kwargs)
=> g(f=10, g=11, args=(12, 2, 3, 4), kwargs={'c': 6, 'b': 5, 'e': 14, 'd': 13})

Solution 5

Motif: *args and **kwargs serves as a placeholder for the arguments that need to be passed to a function call

using *args and **kwargs to call a function

def args_kwargs_test(arg1, arg2, arg3):
    print "arg1:", arg1
    print "arg2:", arg2
    print "arg3:", arg3

Now we'll use *args to call the above defined function

#args can either be a "list" or "tuple"
>>> args = ("two", 3, 5)  
>>> args_kwargs_test(*args)

result:

arg1: two
arg2: 3
arg3: 5


Now, using **kwargs to call the same function

#keyword argument "kwargs" has to be a dictionary
>>> kwargs = {"arg3":3, "arg2":'two', "arg1":5}
>>> args_kwargs_test(**kwargs)

result:

arg1: 5
arg2: two
arg3: 3

Bottomline : *args has no intelligence, it simply interpolates the passed args to the parameters(in left-to-right order) while **kwargs behaves intelligently by placing the appropriate value @ the required place

Share:
648,383
Federer
Author by

Federer

Updated on May 01, 2021

Comments

  • Federer
    Federer about 3 years

    What are the uses for **kwargs in Python?

    I know you can do an objects.filter on a table and pass in a **kwargs argument.  

    Can I also do this for specifying time deltas i.e. timedelta(hours = time1)?

    How exactly does it work? Is it classes as 'unpacking'? Like a,b=1,2?

    • Sergey Orshanskiy
      Sergey Orshanskiy over 10 years
      A remarkably concise explanation here: "* collects all the positional arguments in a tuple", "** collects all the keyword arguments in a dictionary". The key word is collects.
  • Golden Lion
    Golden Lion about 3 years
    def print_all(**kwargs): for key, value in kwargs.items(): print(key+\":\"+value) **kwargs becomes a key/value pair in a dictionary