Accepting arbitrary keyword arguments in Python

Share
Copied to clipboard.
Series: Functions
Trey Hunner smiling in a t-shirt against a yellow wall
Trey Hunner
3 min. read Watch as video Python 3.8—3.12
Python Morsels
Watch as video
03:07

Let's make a function that accepts arbitrary keyword arguments.

Passing keyword arguments to a function

We're going to make a function called say_things that we can call with Trey, ducks=2, cup=1 in order to print out, Trey has... 2 ducks, 1 cup, That's all!. It should work like this:

>>> say_things("Trey", ducks=2)
Trey has...
  2 ducks
That's all!

We'll start with a function that accepts a name argument only:

>>> def say_things(name):
...     print(f"{name} has...")
...     print("That's all!")
...

We can't call this function with the keyword arguments ducks=2 and cup=1 because we will get an error:

>>> say_things("Trey", ducks=2, cup=1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: say_things() got an unexpected keyword argument 'ducks'

Capturing arbitrary keyword arguments

In order to accept any keyword arguments given to this function, we need to use the ** operator. In our function definition we'll put ** and a variable name (things in our case) to tell Python that this function should accept any keyword argument given to it and it should store them in a dictionary which that variable name (things) will point to:

>>> def say_things(name, **things):
...     print(f"{name} has...")
...     print("That's all!")
...

When our say_things function is called, the keys in the things dictionary will be the keyword argument names given (ducks and cup in the aspirational example above) and the values will be the values that were given to those arguments (2 and 1).

To loop over this dictionary, we'll use the items method to get tuples of key-value pairs:

>>> def say_things(name, **things):
...     print(f"{name} has...")
...     for name, count in things.items():
...         print(f"  {count} {name}")
...     print("That's all!")
...

So this new function should accept our name argument and any keyword arguments given to it. For example passing ducks=2 print out 2 ducks:

>>> say_things("Trey", ducks=2)
Trey has...
  2 ducks
That's all!

If we say cup=1 and ideas=3 we'll see those printed out too:

>>> say_things("Trey", ducks=2, cup=1, ideas=3)
Trey has...
  2 ducks
  1 cup
  3 ideas
That's all!

This all works because of **, which is capturing any keyword arguments given to this function into a dictionary.

Arbitrary keyword arguments within Python

You don't really see ** used that often. This operator is most often used with class inheritance in Python, where you're capturing any arguments given to your class and passing them up to some parent class.

However, there is one method on one of the built-in types in Python that uses **: the string format method.

>>> "{n} {item}".format(n=3, item="ducks")
3 ducks

The format method doesn't just accept n and item arguments, it accepts any keyword arguments we can think of to give it. We can see that by looking at the documentation for the format method:

>>> help(str.format)

Help on method_descriptor:

format(...)
    S.format(*args, **kwargs) -> str

You can see that the string format method accepts *args and **kwargs. It's capturing all positional arguments and all keyword arguments given to it. So the format method can accept any arguments you give to it.

Use ** to accept arbitrary keyword arguments

If you need to write a function that accepts arbitrary keyword arguments, you can use the ** operator in your function definition.

Series: Functions

Python, like many programming languages, has functions. A function is a block of code you can call to run that code.

Python's functions have a lot of "wait I didn't know that" features. Functions can define default argument values, functions can be called with keyword arguments, and functions can be written to accept any number of arguments.

To track your progress on this Python Morsels topic trail, sign in or sign up.

0%
A Python Tip Every Week

Need to fill-in gaps in your Python skills? I send weekly emails designed to do just that.

Python Morsels
Watch as video
03:07