C2G: Funktionen als Objekte behandeln

Ich kann Funktionen als First-Class Citizens behandeln: in Variablen speichern, als Rückgabewert verwenden und in Datenstrukturen ablegen.

Lernziele

# Lernziel Beantwortet in
1 Ich kann eine Funktion in einer Variable speichern und diese Variable aufrufen, um die Funktion auszuführen. 1. Funktion einer Variable zuweisen
2 Ich kann eine Funktion schreiben, die eine andere Funktion zurückgibt. 2. Funktion als Rückgabewert
3 Ich kann Funktionen in Listen oder Dictionaries speichern und gezielt abrufen. 3. Funktionen in Datenstrukturen speichern

Überblick

In Python sind Funktionen vollwertige Objekte, just wie Zahlen oder Strings. Man kann sie in Variablen speichern, zurückgeben und in Datenstrukturen ablegen.


1. Funktion einer Variable zuweisen

Man kann einfach eine Funktion einer Variablen zuweisen und dann über diese Variable aufrufen.

# Lambda in einer Variable speichern
greet = lambda name: f"Hallo, {name}!"

# Über die Variable aufrufen
print(greet("Anna"))  # Hallo, Anna!

Benannte Funktion zuweisen

Bestehende Funktionen können direkt als Wert zugewiesen werden:

# Methodenreferenz statt Lambda
to_upper = str.upper

print(to_upper("hallo"))  # HALLO

Verschiedene Funktionstypen

# Einfache Berechnung
double_it = lambda x: x * 2
print(double_it(5))  # 10

# Predicate: gibt boolean zurück
is_even = lambda x: x % 2 == 0
print(is_even(4))  # True
print(is_even(7))  # False

# Funktion, die nichts zurückgibt
printer = print
printer("Hallo Welt")  # Hallo Welt

2. Funktion als Rückgabewert

Eine Funktion kann eine andere Funktion zurückgeben. Das ermöglicht es, Funktionen dynamisch zu erzeugen.

# Gibt eine Funktion zurück, die mit dem gegebenen Faktor multipliziert
def create_multiplier(factor: int):
    return lambda x: x * factor

# Neue Funktionen erzeugen
double_it = create_multiplier(2)
triple_it = create_multiplier(3)

print(double_it(5))   # 10
print(triple_it(5))   # 15
print(double_it(10))  # 20

Weiteres Beispiel: Begrüssung mit Präfix

def create_greeter(prefix: str):
    return lambda name: f"{prefix} {name}!"

formal = create_greeter("Guten Tag,")
casual = create_greeter("Hey")

print(formal("Herr Müller"))  # Guten Tag, Herr Müller!
print(casual("Max"))           # Hey Max!

3. Funktionen in Datenstrukturen speichern

Man kann Funktionen in Listen oder Dictionaries ablegen und gezielt abrufen.

In einer Liste

# Operationen mit Namen als Tuple speichern
operations = [
    ("add",      lambda a, b: a + b),
    ("subtract", lambda a, b: a - b),
    ("multiply", lambda a, b: a * b)
]

for name, fn in operations:
    result = fn(10, 3)
    print(f"{name}(10, 3) = {result}")
# add(10, 3) = 13
# subtract(10, 3) = 7
# multiply(10, 3) = 30

In einem Dictionary

# Temperatur-Konverter in einem Dictionary
converters = {
    "fahrenheit": lambda c: c * 9 / 5 + 32,
    "kelvin":     lambda c: c + 273.15
}

# Gezielt abrufen und aufrufen
unit = "kelvin"
convert = converters[unit]
print(f"25°C in {unit}: {convert(25.0)}")
# 25°C in kelvin: 298.15

unit = "fahrenheit"
convert = converters[unit]
print(f"25°C in {unit}: {convert(25.0)}")
# 25°C in fahrenheit: 77.0

Das Dictionary-Pattern ist besonders nützlich, um if/else-Ketten zu ersetzen:

# Statt:
def convert(value: float, unit: str) -> float:
    if unit == "fahrenheit":
        return value * 9 / 5 + 32
    elif unit == "kelvin":
        return value + 273.15
    else:
        raise ValueError(f"Unbekannte Einheit: {unit}")

# Einfacher:
def convert(value: float, unit: str) -> float:
    return converters[unit](value)

This site uses Just the Docs, a documentation theme for Jekyll.