def foo(arg1, /, arg2, *, arg3):
print(arg1, arg2, arg3)
Have you seen this syntax in Python functions? Let's unpack it:
- Parameters listed before the
/
parameter are positional-only1. - Parameters after the
*
parameter are keyword-only2. - Parameters in between can be either positional or keyword-only.
Using this can be especially helpful if you provide your code as a shared library. It allows you to maintain control over how your function is called, in case you update the argument list in the future.
An example:
def calculate(x: int, y: int, /, *, method: str) -> None:
if method != "multiply":
raise ValueError("This calculator supports only multiplication. 🫣")
print(f"{x} × {y} = {x * y}")
>>> calculate(1, 2, 'multiply')
TypeError: calculate() takes 2 positional arguments but 3 were given
>>> calculate(x=2, y=3, method='multiply')
TypeError: calculate() got some positional-only arguments passed as keyword arguments: 'x, y'
>>> calculate(1, 2, 3, method='multiply')
TypeError: calculate() takes 2 positional arguments but 3 positional arguments (and 1 keyword-only argument) were given
>>> calculate(2, 3, method="multiply")
2 × 3 = 6
-
docs.python.org: What does the slash(/) in the parameter list of a function mean? ↩
-
peps.python.org PEP 457 – Notation For Positional-Only Parameters ↩