The Python positional-only parameter has been introduced with the Python 3.8 release. It is a way to specify which parameters must be positional-only arguments – i.e. which parameters cannot be given as keyword-parameters. It uses the / parameter syntax. Elements positioned on the left side will be then turned into positional-only parameters.
def f(a, b, /, c): ...
The above method will only accepts calls of the following form:
python> f(1, 2, 3)
python> f(1, 2, c=3)
Note: c can be either given a position or keyword argument.
On the contrary, the following calls will raise a TypeError: f() got some positional-only arguments passed as keyword arguments error as a and b – being on the left of / – cannot be exposed as possible keyword-arguments:
python> f(1, b=2, 3)
python> f(1, b=2, c=3)
python> f(a=1, b=2, 3)
Use cases
The / positional-only parameter syntax is helpful in the following use-cases:
-
It precludes keyword arguments from being used when the parameter’s name is not necessary, confusing or misleading e.g.
len(obj=my_list). As stated in the documentation, theobjkeyword argument would here impairs readability. -
It allows the name of the parameter to be changed in the future without introducing breaking changes in he client as they can still be passed through
**kwargsto be used in two ways:
def transform(name, /, **kwargs):
print(name.upper())
In the above snippet, you can access the name‘s value either using name or kwargs.get("name").
Last but not the least, it can also be used to prevent overwriting pre-set keyword-arguments in methods that still need to accept arbitrary keyword arguments (via kwargs):
def initialize(name="unknown", /, **kwargs):
print(name, kwargs)
The name keyword-argument is protected and could not be overwritten, even if mistakenly captured a second time by the kwargs argument:
python> initialize(name="olivier")
unknown {'name': 'olivier'}
Notes:
- Python does not allow positional arguments after keyword arguments because of the left-side/right-side of the
/operator thingy. - Python does not allow positional arguments after keyword arguments because of the left-side/right-side of the
*operator thingy. *argsare collecting as positional arguments.**kwargsare collecting as keyword-arguments.
