from IPython.core.display import HTML

HTML(open("custom.html", "r").read())
Creative Commons License This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.

Copyright (C) 2014-2023 Scientific IT Services of ETH Zurich,
Contributing Authors: Uwe Schmitt, Mikolaj Rybniski

11. More about function arguments (args and kwargs)¶

Use in function declarations¶

Python offers mechanisms for handling arbritrary function arguments which are not specified in the function declaration.

Here the last variable args, preceeded by a * captures all extra arguments when called with more than the one specified m0 argument.

The name args is arbitrary.

def my_max(m0, *args):
    print("got", m0, "and", args)
    result = m0
    for value in args:
        if value > result:
            result = value
    return result


print(my_max(1))
print(my_max(1, 2, 3))
got 1 and ()
1
got 1 and (2, 3)
3

This also works in other combinations like:

def test_0(*args):
    print("args in test_0 is", args)


def test_1(a, b, *c):
    print("c in test_1 is", c)


test_0()
test_0(1, 2, 3)

test_1(1, 2)
test_1(1, 2, 3, 4, 5, 6)
args in test_0 is ()
args in test_0 is (1, 2, 3)
c in test_1 is ()
c in test_1 is (3, 4, 5, 6)

Further one can capture arbitrary keyword arguments using **:

def test_2(a, b, **kw):
    print("kw is", kw)


test_2(1, b=3, c=4, d=5)
kw is {'c': 4, 'd': 5}

And in combinations:

def test_4(*args, **kw):
    print("args is", args)
    print("kw is", kw)


test_4(1, 2, 3, a=42)
args is (1, 2, 3)
kw is {'a': 42}

Use when calling a function¶

There is an inverse mechanism to unpack tuples/lists and dictionaries when calling a function:

def test_5(a, b, c):
    print("got", a, b, c)


data = (1, 2, 3)

try:
    # does not work: data as a tuple is considered as one single
    # value:
    test_5(data)
except Exception as e:
    print("failed:", e)

# unpacking works:
test_5(*data)
failed: test_5() missing 2 required positional arguments: 'b' and 'c'
got 1 2 3
def test_6(a, b, *c):
    print("got", a, b, c)


data = (1, 2, 3)
test_6(0, *data)
got 0 1 (2, 3)

And with a dictionary:

def test_7(a, b, c, d, **e):
    print("got", a, b, c, d, e)


data = {"a": 1, "c": 3, "e": 5}

test_7(b=2, d=4, **data)
got 1 2 3 4 {'e': 5}

Exercise section¶

Repeat all code examples and play with them.

Optional exercise*¶

Write a function which takes an arbitrary number of dictionaries and combines them. Keyword arguments finally also should be merged into the result. E.g.

merge({1: 2}, {"a": 3, "b": 4}, b=5, c=6))

should return

{1: 2, "a": 3, "b": 5, "c": 6}

(up to the order of dictionaries). Hint: dictionaries have an update method. Don't forget to handle the case of keyword arguments only !.