Related article:
- Keyword (Named) Arguments in Python: How to Use Them
- Asterisks in Python: what they are and how to use them
- Positional vs Keyword Arguments
- Tuple Unpacking
- Accepting any number of arguments to a function
- Keyword-Only Function Arguments
Transcript:
Let's make a function that accepts arbitrary keyword arguments.
Calling With Arbitrary Keyword Arguments
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 in Python Library
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.
Summary
If you need to write a function that accepts arbitrary keyword arguments, you can use the **
operator in your function definition.
from Planet Python
via read more
No comments:
Post a Comment