Let’s have a look of its syntax:
def f(a, b, *args, option=True): ...
Or, if you don’t want to collect
*args, you can do the following:
def f(a, b, *, option=True): ...
option is the keyword-only argument. The only way to access it is to explicitly call
f(a, b, option=True).
One of the problems it is solving is that the values of keyword arguments can be passed without specifying the keyword(s); or, put it in another way, keyword arguments are not keyword-only. And in this case it is possible to actually pass a value as a positional argument to a keyword argument accidentally: example.
The other benefit of using keyword-only arguments is you can make youre APIs ‘future change proof’. To put it in another way: using keyword-only arguments allows you to add new keyword (-only) arguments without breaking API. Let’s see this example.
Without this feature, like what’s in Python 2, you have to use
**kwargs and do the extra handling/parsing
Enough said, a little summary:
If you somehow are writing for a Python 3 only codebase, I highly recommend making all your keyword arguments keyword only, especially keyword arguments that represent “options”
Now, let’s talk about positional-only arguments. Say what?
Positional-only arguments are parameters that cannot be specified by keywords, and they are passed only
by mapping the positions to the formal arguments of a function. Many python
builtin functions are actually
allowing only positoinal-only arguments, for example, function
In : pow? Signature: pow(x, y, z=None, /) Docstring: Equivalent to x**y (with two arguments) or x**y % z (with three arguments) Some types, such as ints, are able to use a more efficient algorithm when invoked using the three argument form. Type: builtin_function_or_method In : pow(x=2, y=3) --------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-3-3c1748947c84> in <module>() ----> 1 pow(x=2, y=3) TypeError: pow() takes no keyword arguments
Noticed the slash
/ at the end of the argument list? That means all arguments before it are
positional-only. You can sometimes see such syntax in some of the
docstrings of certain
builtin functions or library functions.
Currently (25.09.2018) there is no way to write ‘positional-only’ arguments in Python 3, to use such feature, you need to use Python C API (in other words, implement functions in C). PEP 570 was already proposed for implementing such syntax in Python, however, it is not yet implementd as we speak (25.09.2018).
Given such feature in mind, the following syntax gives the complete picture of all possible types of arguments in a function signature:
def name(positional_only_parameters, /, positional_or_keyword_parameters, *, keyword_only_parameters):
One last note, even in the above newer syntax, non-default arguments must still appear before default