2. Defining function with arbitrary number of arguments

2.1. Recap information about function parameters

def echo(a, b):
    print(a)
    print(b)


echo(1, 2)       # pozycyjne
echo(a=1, b=2)   # nazwane, kolejność nie ma znaczenia
echo(b=2, a=1)   # nazwane, kolejność nie ma znaczenia
echo(1, b=2)     # pozycyjne i nazwane
echo(a=1, 2)     # SyntaxError: positional argument follows keyword argument

2.2. Arbitrary number of positional arguments

  • * in this context, is not multiplication in mathematical sense

  • * is used for positional arguments

  • args is a convention, but you can use any name

  • *args unpacks to tuple

def echo(*args):
    print(args)


echo()                        # ()
echo(1)                       # (1,)
echo(2, 3)                    # (2, 3)
echo('red', 2)                # ('red', 2)
echo('red', 'green', 'blue')  # ('red', 'green', 'blue')
def echo(a, b, c=0, *args):
    print(a)       # 1
    print(b)       # 2
    print(c)       # 0
    print(args)    # ()


echo(1, 2)
def echo(a, b, c=0, *args):
    print(a)       # 1
    print(b)       # 2
    print(c)       # 3
    print(args)    # (4, 5, 6)


echo(1, 2, 3, 4, 5, 6)

2.3. Arbitrary number of keyword arguments

  • ** in this context, is not power in mathematical sense

  • ** is used for keyword arguments

  • kwargs is a convention, but you can use any name

  • **kwargs unpacks to dict

def echo(**kwargs):
    print(kwargs)


echo(a=10)                                      # {'a': 10}
echo(color='red')                               # {'color': 'red'}
echo(first_name='Jan', last_name='Twardowski')  # {'first_name': 'Jan', 'last_name': Twardowski}
def echo(a, b, c=0, **kwargs):
    print(a)       # 1
    print(b)       # 2
    print(c)       # 0
    print(kwargs)  # {}


echo(1, 2)
def echo(a, b, c=0, **kwargs):
    print(a)       # 1
    print(b)       # 2
    print(c)       # 0
    print(kwargs)  # {'d':7, 'e': 8}


echo(1, 2, d=7, e=8)
def echo(a, b, c=0, **kwargs):
    print(a)       # 1
    print(b)       # 2
    print(c)       # 3
    print(kwargs)  # {'d':7, 'e': 8}


echo(1, 2, 3, d=7, e=8)

2.4. Arbitrary number of positional and named arguments

def echo(a, b, c=0, *args, **kwargs):
    print(a)       # 1
    print(b)       # 2
    print(c)       # 3
    print(args)    # (4, 5, 6)
    print(kwargs)  # {}


echo(1, 2, 3, 4, 5, 6)
def echo(a, b, c=0, *args, **kwargs):
    print(a)       # 1
    print(b)       # 2
    print(c)       # 0
    print(args)    # ()
    print(kwargs)  # {'d':7, 'e': 8}


echo(1, 2, d=7, e=8)
def echo(a, b, c=0, *args, **kwargs):
    print(a)       # 1
    print(b)       # 2
    print(c)       # 3
    print(args)    # (4, 5, 6)
    print(kwargs)  # {'d':7, 'e': 8}


echo(1, 2, 3, 4, 5, 6, d=7, e=8)

2.5. Keyword only

  • All arguments after * is keyword only

  • Since Python 3.8 there will be / to indicate positional only arguments

def echo(a, *, b):
    print(a)
    print(b)

echo(1, b=2)
# 1
# 2

echo(1, 2)
# TypeError: echo() takes 1 positional argument but 2 were given

echo(1)
# TypeError: echo() missing 1 required keyword-only argument: 'b'

2.6. Use cases

def add(*args):
    total = 0

    for arg in args:
        total += arg

    return total


add()            # 0
add(1)           # 1
add(1, 4)        # 5
add(3, 1)        # 4
add(1, 2, 3, 4)  # 10
Listing 92. Converts arguments between different units
def kelvin_to_celsius(*degrees):
    return [x+273.15 for x in degrees]


kelvin_to_celsius(1)
# [274.15]

kelvin_to_celsius(1, 2, 3, 4, 5)
# [274.15, 275.15, 276.15, 277.15, 278.15]
Listing 93. Generate HTML list from function arguments
def html_list(*args):
    print('<ul>')

    for element in args:
        print(f'<li>{element}</li>')

    print('</ul>')


html_list('apple', 'banana', 'orange')
# <ul>
# <li>apple</li>
# <li>banana</li>
# <li>orange</li>
# </ul>
Listing 94. Intuitive definition of print function
def print(*values, sep=' ', end='\n', ...):
    return sep.join(values) + end

2.7. Assignments

2.7.1. Numeric Values, positional only

  1. Stwórz funkcję is_numeric

  2. Funkcja może przyjmować tylko argumenty pozycyjne

  3. Podawane argumenty mogą być dowolnego typu

  4. Za pomocą isinstance() sprawdź:

    • Zwróć True jeżeli wszystkie argumenty są tylko typów int lub float

    • Zwróć False jeżeli którykolwiek jest innego typu

  5. Przez numeryczną wartością rozumiemy

  6. Nie używaj all() oraz any()

The whys and wherefores
  • Definiowanie i uruchamianie funkcji

  • Wiele argumentów pozycyjnych

  • Sprawdzanie przypadków brzegowych (niekompatybilne argumenty)

  • Parsowanie argumentów funkcji

  • Rzutowanie i konwersja typów

2.7.2. Numeric Values, positional and keyword

  1. Stwórz funkcję is_numeric

  2. Funkcja może przyjmować zarówno argumenty pozycyjne jak i nazwane

  3. Podawane argumenty mogą być dowolnego typu

  4. Za pomocą isinstance() sprawdź:

    • Zwróć True jeżeli wszystkie argumenty są tylko typów int lub float

    • Zwróć False jeżeli którykolwiek jest innego typu

  5. Nie używaj all() oraz any()

The whys and wherefores
  • Definiowanie i uruchamianie funkcji

  • Wiele argumentów pozycyjnych i nazwanych

  • Sprawdzanie przypadków brzegowych (niekompatybilne argumenty)

  • Parsowanie argumentów funkcji

  • Rzutowanie i konwersja typów