- Keyword (Named) Arguments in Python: How to Use Them
- Asterisks in Python: what they are and how to use them
- Positional vs Keyword Arguments
- Accepting any number of arguments to a function
Let's define a function that accepts a keyword-only argument.
Accepting Multiple Positional Argument
greet function accepts any number of positional arguments:
>>> def greet(*names):... for name in names:... print("Hello", name)...
If we give it some names, it's going to print out
Hello, and then the name, for each of those names:
>>> greet("Trey", "Jo", "Ian")Hello TreyHello JoHello Ian
It does this through the
* operator, which is capturing all the positional arguments given to this function.
Positional and Keyword-Only Argument
If we wanted to allow the greeting (
Hello) to be customized we could accept a
>>> def greet(*names, greeting):... for name in names:... print(greeting, name)...
We might try to call this new
greet function like this:
>>> greet("Trey", "Hi")Traceback (most recent call last): File "<stdin>", line 1, in <module>TypeError: greet() missing 1 required keyword-only argument: 'greeting'
But that gives us an error. The error says that
greet is missing one required keyword-only argument
That error is saying is that
greeting is a required argument because it doesn't have a default value and it must be specified as a keyword argument when we call this function.
So if we want to customize
greeting, we can pass it in as a keyword argument:
>>> greet("Trey", greeting="Hi")Hi Trey>>> greet("Trey", greeting="Hello")Hello Trey
We probably want
greeting to actually have a default value of
Hello.We can do that by specifying a default value for the
>>> def greet(*names, greeting="Hello"):... for name in names:... print(greeting, name)...>>> greet("Trey", "Jo")Hello TreyHello Jo
greeting is after that
*names in our function definition, Python sees
greeting as a keyword-only argument: an argument that can only be provided as a keyword argument when this function is called.
It can only be given by its name like this:
>>> greet("Trey", "Jo", greeting="Hi")Hi TreyHi Jo
Keyword-Only Arguments in Built-in Functions
This is actually something you'll see in some of Python's built-in functions.For example, the
>>> help(print)Help on built-in function print in module builtins:print(...) print(value, ..., sep=' ', end='\n', file=sys.stdout, flush=False)
Note that the documentation for
* syntax, but that
If we look at the documentation for
greet, you'll see how keyword-only arguments usually show up in documentation:
>>> help(greet)Help on function greet in module __main__:greet(*names, greeting='Hello')
Everything after that
greeting in this case), can only be specified as a keyword argument.
Keyword-Only Arguments without Capturing All Positional Arguments
It is also possible to make a function that doesn't capture any number of positional arguments, but does have some keyword-only arguments.The syntax for this is really weird.
Let's make a
multiply function that accepts
>>> def multiply(*, x, y):... return x * y...
y means that they must be specified as keyword arguments.
So, if we were to try to call
multiply with two positional arguments, we'll get an error:
>>> multiply(1, 2)Traceback (most recent call last): File "<stdin>", line 1, in <module>TypeError: multiply() takes 0 positional arguments but 2 were given
To call this function, we have to specify
y as keyword arguments:
>>> multiply(x=1, y=2)2
If we call this function with nothing you'll see an error message similar to what we saw before about required keyword-only arguments:
>>> multiply()Traceback (most recent call last): File "<stdin>", line 1, in <module>TypeError: multiply() missing 2 required keyword-only arguments: 'x' and 'y'
Keyword-Only Arguments in the Standard Library
You'll actually sometimes see this
* thing on its own within the Python standard library.For example in the
chown function in the
os module (used for changing the ownership of a file) uses the a lone
* to specify keyword-only arguments:
chown(path, uid, gid, *, dir_fd=None, follow_symlinks=True) Change the owner and group id of path to the numeric uid and gid.
chown function documentation shows
gid, and then a
* (which isn't an argument itself), and then
* is a way of noting that everything after that point is a keyword-only argument.
The last two arguments,
follow_symlinks can only be specified by their name when the
chown function is called.
So, whenever you see a function that uses
* to capture any number of positional arguments (e.g.
*args in the function definition), note that any arguments defined after that
* capturing can only be specified as a keyword argument (they're keyword-only arguments).
Also if you see a function that has an
* on its own with a comma after it, that means that every argument after that point, is a keyword only argument it must be specified by its name when that function is called.