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.
Let's define a function that accepts a keyword-only 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 Trey Hello Jo Hello Ian
It does this through the
* operator, which is capturing all the positional arguments given to this function.
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
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 Trey Hello 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 Trey Hi Jo
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.
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'
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).
Hello friendly web visitor! 👋
This page is part of Python Morsels, an online Python skill-building service.
The best way to learn is by doing. In the case of Python that means writing Python code. If you'd like to improve your Python skills every week, try out Python Morsels by entering your email below to create an account.
Python Morsels topics pages are free and the first month's worth of exercises is free as well. You don't need to enter payment details to sign up.
You can find explanations of many other Python topics by signing up below.