ProgrammingBackend Developer

How does the mechanism of working with positional and keyword arguments in Python operate? What are the nuances of the argument order when defining and calling a function, and what are the purposes of positional-only and keyword-only parameters?

Pass interviews with Hintsage AI assistant

Answer.

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.

Types of Parameters

  1. Positional (usually listed first): values are passed in the order specified.
  2. Keyword: explicitly specified by name.
  3. Positional-only: declared before the / symbol (Python 3.8+), cannot be specified by name.
  4. Keyword-only: declared after *, 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

Nuances

  • Order of parameters: (positional-only) / (positional-or-keyword) * (keyword-only)
  • With incorrect argument order, a SyntaxError or TypeError will occur.
  • *args collects additional positional; **kwargs - keyword.

Trick Question.

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?

Answer:

  • For the function 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.
  • You can specify parameters by name if they are not defined as positional-only.
  • If the function is declared as def f(a, b, /, c):, then a and b can only be passed positionally.

Example:

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

Examples of real errors due to lack of knowledge about the nuances of this topic


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.