4.1. Parameter Syntax

4.1.1. Recap

def echo(a, b, c=3):
     print(a, b, c)


echo(1, 2)              # 1 2 3
echo(1, b=2)            # 1 2 3
echo(1, c=3)            # TypeError: echo() missing 1 required positional argument: 'b'
echo(1, 2, 3)           # 1 2 3
echo(1, 2, c=3)         # 1 2 3
echo(1, b=2, c=3)       # 1 2 3
echo(a=1, b=2, c=3)     # 1 2 3

4.1.2. Keyword-only Parameters

  • All parameters after * must be keyword-only

def echo(a, *, b, c=3):
    print(a, b, c)


echo(1, 2)              # TypeError: echo() takes 1 positional argument but 2 were given
echo(1, b=2)            # 1 2 3
echo(1, c=3)            # TypeError: echo() missing 1 required keyword-only argument: 'b'
echo(1, 2, 3)           # TypeError: echo() takes 1 positional argument but 3 were given
echo(1, 2, c=3)         # TypeError: echo() takes 1 positional argument but 2 positional arguments (and 1 keyword-only argument) were given
echo(1, b=2, c=3)       # 1 2 3
echo(a=1, b=2, c=3)     # 1 2 3

4.1.3. Positional-only Parameters

  • Since Python 3.8: PEP 570 -- Python Positional-Only Parameters

  • All parameters before / must be positional-only

def echo(a, /, b, c=3):
    print(a, b, c)


echo(1, 2)              # 1 2 3
echo(1, b=2)            # 1 2 3
echo(1, c=3)            # TypeError: echo() missing 1 required positional argument: 'b'
echo(1, 2, 3)           # 1 2 3
echo(1, 2, c=3)         # 1 2 3
echo(1, b=2, c=3)       # 1 2 3
echo(a=1, b=2, c=3)     # TypeError: echo() got some positional-only arguments passed as keyword arguments: 'a'

4.1.4. Positional and Keyword Parameters

def echo(a, /, b, *, c=3):
    print(a, b, c)


echo(1, 2)              # 1 2 3
echo(1, b=2)            # 1 2 3
echo(1, c=3)            # TypeError: echo() missing 1 required positional argument: 'b'
echo(1, 2, 3)           # TypeError: echo() takes 2 positional arguments but 3 were given
echo(1, 2, c=3)         # 1 2 3
echo(1, b=2, c=3)       # 1 2 3
echo(a=1, b=2, c=3)     # TypeError: echo() got some positional-only arguments passed as keyword arguments: 'a'

4.1.5. Use Cases

https://docs.python.org/3/library/functions.html#sorted:

sorted(iterable, *, key=None, reverse=False)

https://docs.python.org/3/library/functions.html#sum:

sum(iterable, /, start=0)
def add(a, b, /):
    return a + b
def divmod(a, b, /):
    return (a // b, a % b)
def quantiles(dist, /, *, n=4, method='exclusive')
    ...

4.1.6. Assignments

Code 4.1. Solution
"""
* Assignment: Function Parameter Syntax Kwargs
* Complexity: easy
* Lines of code: 2 lines
* Time: 3 min

English:
    1. Create function `set_position`
    2. Function takes two arguments `x`, `y` and always returns `None`
    3. Arguments must be passed only as keywords
    4. Test function by running with keyword arguments
    5. Test function by running with positional arguments
    6. Compare result with "Tests" section (see below)

Polish:
    1. Stwórz funkcję `set_position`
    2. Funkcja przyjmuje dwa argumenty `x`, `y` i zawsze zwraca `None`
    3. Argumenty można podawać tylko nazwanie (keyword)
    4. Przetestuj funkcję uruchamiając z nazwanymi parametrami
    5. Przetestuj funkcję uruchamiając z pozycyjnymi parametrami
    6. Porównaj wyniki z sekcją "Tests" (patrz poniżej)

Tests:
    >>> from inspect import isfunction
    >>> assert callable(set_position)
    >>> assert isfunction(set_position)

    >>> set_position(x=1, y=2)

    >>> set_position()
    Traceback (most recent call last):
    TypeError: set_position() missing 2 required keyword-only arguments: 'x' and 'y'

    >>> set_position(1)
    Traceback (most recent call last):
    TypeError: set_position() takes 0 positional arguments but 1 was given

    >>> set_position(1, 2)
    Traceback (most recent call last):
    TypeError: set_position() takes 0 positional arguments but 2 were given

    >>> set_position(1, y=1)
    Traceback (most recent call last):
    TypeError: set_position() takes 0 positional arguments but 1 positional argument (and 1 keyword-only argument) were given

    >>> set_position(x=1, 2)
    Traceback (most recent call last):
    SyntaxError: positional argument follows keyword argument
"""


Code 4.2. Solution
"""
* Assignment: Function Parameter Syntax Args
* Complexity: easy
* Lines of code: 2 lines
* Time: 3 min
* Warning: This assignment will work only in Python 3.8+

English:
    1. Create function `take_damage`
    2. Function takes one argument `dmg` and always returns `None`
    3. Argument must be passed only as positional
    4. Test function by running with positional arguments
    5. Test function by running with keyword arguments
    6. Compare result with "Tests" section (see below)

Polish:
    1. Stwórz funkcję `take_damage`
    2. Funkcja przyjmuje jeden argument `dmg` i zawsze zwraca `None`
    3. Argument można podawać tylko pozycyjnie
    4. Przetestuj funkcję uruchamiając z pozycyjnymi parametrami
    5. Przetestuj funkcję uruchamiając z nazwanymi parametrami
    6. Porównaj wyniki z sekcją "Tests" (patrz poniżej)

Tests:
    >>> from inspect import isfunction
    >>> assert callable(take_damage)
    >>> assert isfunction(take_damage)

    >>> take_damage(1)
    >>> take_damage(1, 2)
    Traceback (most recent call last):
    TypeError: take_damage() takes 1 positional argument but 2 were given
    >>> take_damage()
    Traceback (most recent call last):
    TypeError: take_damage() missing 1 required positional argument: 'dmg'
    >>> take_damage(dmg=1)
    Traceback (most recent call last):
    TypeError: take_damage() got some positional-only arguments passed as keyword arguments: 'dmg'
"""