Positional-only arguments in Python
The ability to specify positional-only arguments using the / marker in function definitions is among the many new improvements to the Python language coming in the upcoming }}">3.8 release. This addition to syntax has performance benefits and enables better API design. Let's look at the motivation behind positional-only arguments and how to use it, with examples.
Background
Keyword-only arguments have been available in Python with the * marker, and addition of / marker for positional-only arguments improves the language’s consistency. With positional-or-keyword parameters, the mix of calling conventions is not always desirable. Consider these examples:
- Some function parameters already have semantic meaning: namedtuple(typenames, field_names, …)
- The parameter name has no true external meaning: arg1, arg2, …, etc for min()
If the users start using a keyword argument, the library author cannot rename the parameter because it would be a breaking change. In case of min(), the name of the parameter provides no intrinsic value and forces the author to maintain its name forever since callers might pass arguments as a keywords. This problem is solved by positional-only arguments. In addition, the parsing and handling of positional-only arguments is faster.
How to use positional-only arguments
To specify arguments as positional-only, a / marker should be added after all those arguments in the function definition. Take this example:
{{< highlight python "hl_lines=1">}} def pow(x, y, /, mod=None): r = x ** y if mod is not None: r %= mod return r {{< /highlight >}}
The following would apply:
- All parameters to the left of / (in this case, x and y) can only be passed positionally.
- mod can be passed positionally or with a keyword.
Another example:
- Once a positional-only parameter is specified with a default, the following positional-only and positional-or-keyword parameters need to have defaults as well (in this case, prettify).
- Positional-only parameters which do not have default values are required positional-only parameters (in this case, items).
The generic case
A function definition, with all flavors of argument-passing variants, would look like this:
When to use positional-only arguments
- Use positional-only if names do not matter or have no meaning, and there are only a few arguments which will always be passed in the same order.
- Use keyword-only when names have meaning and the function definition is more understandable by being explicit with names.
Positional-only arguments were proposed in PEP 570, and it's worth taking a look at the doc to understand the feature in more detail.