In Python, a function can declare parameters of four types: positional, keyword, positional-only, and keyword-only. Their differences affect how values are passed when calling the function.
/ symbol (Python 3.8+), cannot be specified by name.*, can only be specified by key.# Example of all types def func(a, b, /, c, *, d, e): print(a, b, c, d, e) func(1, 2, 3, d=4, e=5) # OK # func(a=1, b=2, 3, d=4, e=5) # Error: a, b - positional-only
SyntaxError or TypeError will occur.*args collects additional positional; **kwargs - keyword.How do the following function declarations differ:
def f(a, b, c): ... def f(a, b, c=1): ... def f(a, b=1, c=2): ... def f(a=1, b=2, c=3): ...
And is it true that all these functions can be called with both positional and keyword parameters?
def f(a, b, c):, you cannot call it with keyword-only arguments because all can be passed either positionally or by keyword, but all arguments are required.def f(a, b, /, c):, then a and b can only be passed positionally.def f(a, b, c=10): print(a, b, c) f(1, 2) # OK, c=10 by default f(a=1, b=2, c=3) # OK # But: def f(a, b, /, c=10): ... f(1, 2) # OK f(a=1, b=2, c=3) # Error! a and b are positional-only
Story
A developer implemented a function that, by convention, should only accept parameters by name: logging with many parameters, some of which are optional. However, they forgot to declare *, and users accidentally passed parameters in different orders positionally, leading to incorrect logging and hard-to-trace errors.
Story
In a REST API project, due to an implicit agreement on the order of arguments (they used *args and did not restrict parameters by name), requests stopped working after implementing a new version of the client — because args shifted. They fixed it by introducing explicit * and specifying only keyword arguments.
Story
In a large corporate project, a function was extended with new parameters with default values, but due to erroneous calls with positional values, the old code started substituting values in other parameters, causing incorrect data processing. It turned out that parameters should have been made keyword-only.