11 Fortgeschrittene Funktionstechniken
Closures, Decorators und verwandte Konzepte sind Kernelemente der funktionalen Programmierung in Python. Sie ermöglichen sauberen, wiederverwendbaren und eleganten Code.
Ein Closure ist eine verschachtelte Funktion, die auf Variablen der äußeren Funktion auch nach deren Ausführung noch zugreifen kann. Dadurch entsteht ein erhaltener Zustand ohne Verwendung von Klassen.
def greeting(name):
# innere Funktion greift auf 'name' zu
def say_hello():
print(f'Hallo {name}!')
return say_hello
greet = greeting('Stefan')
greet() # Ausgabe: Hallo Stefan!
def counter():
count = 0
def increment():
# Zugriff auf äußere Variable mit nonlocal
nonlocal count
count += 1
return count
return increment
c = counter()
print(c()) # 1
print(c()) # 2
Lambda-Funktionen sind anonyme Funktionen, meist in einer Zeile geschrieben. Sie sind besonders praktisch in Kombination mit map, filter und anderen höherwertigen Funktionen.
Syntax:
lambda arguments: expression
Beispiel:
add = lambda x, y: x + y
print(add(3, 5)) # 8
Eine Higher-Order Function ist eine Funktion, die andere Funktionen entgegennimmt oder zurückgibt.
def apply_twice(func, value):
return func(func(value))
print(apply_twice(lambda x: x + 1, 3)) # 5
map, filter, reducemap(func, iterable): Wendet func auf jedes Element an.filter(func, iterable): Filtert Elemente basierend auf Wahrheitswert von func.reduce(func, iterable, initial): Akkumuliert alle Elemente zu einem einzigen Wert.numbers = [1, 2, 3, 4, 5]
# map: Transformation
squared = list(map(lambda x: x**2, numbers)) # [1, 4, 9, 16, 25]
# filter: Bedingung
even = list(filter(lambda x: x % 2 == 0, numbers)) # [2, 4]
# reduce: Akkumulation
from functools import reduce
summed = reduce(lambda acc, x: acc + x, numbers, 0) # 15
Vorkonfigurierte Funktionen mit functools.partial erlauben das Vorbelegen von Argumenten einer Funktion. Das ist nützlich, wenn man spezialisierte Varianten einer Funktion benötigt.
from functools import partial
def power(base, exponent):
return base ** exponent
square = partial(power, exponent=2)
cube = partial(power, exponent=3)
print(square(5)) # 25
print(cube(2)) # 8
partial erstellt eine neue Funktion mit fixierten Parametern.Funktionen, die andere Funktionen erzeugen – meist Closures. Ideal, wenn man eine Reihe verwandter Funktionen mit leicht unterschiedlichem Verhalten benötigt.
def make_multiplier(factor):
def multiply(x):
return x * factor
return multiply
double = make_multiplier(2)
print(double(10)) # 20
factor bleibt in jeder zurückgegebenen Funktion erhalten.Ein Decorator erweitert das Verhalten einer Funktion, ohne ihren Code zu verändern. Er basiert auf Closures und Higher-Order Functions.
def my_decorator(func):
def wrapper():
print('Before the function runs.')
func()
print('After the function runs.')
return wrapper
@my_decorator
def say_hello():
print('Hello!')
say_hello()
@my_decorator ersetzt say_hello durch wrapper.Decorator-Funktionen können Argumente übernehmen, wenn sie flexibel konfiguriert werden sollen. Dazu ist eine zusätzliche Verschachtelung notwendig.
def logger(func):
def wrapper(*args, **kwargs):
print(f'Arguments: {args}, {kwargs}')
return func(*args, **kwargs)
return wrapper
@logger
def add(x, y):
return x + y
add(3, 5)
*args und **kwargs fangen alle Argumente ab.def speaker(volume):
def decorator(func):
def wrapper():
print(f'[{volume.upper()}]')
func()
return wrapper
return decorator
@speaker('quiet')
def whisper():
print('psst...')
whisper()
speaker("quiet") gibt den eigentlichen Decorator zurück.@staticmethod: Definiert eine Methode ohne self@classmethod: Zugriff auf Klasse statt Instanz@property: Erlaubt methodenartigen Zugriff auf Attributeclass Circle:
def __init__(self, radius):
self._radius = radius
@property
def area(self):
return 3.14 * self._radius ** 2
@decorator_one
@decorator_two
def some_function():
pass
decorator_two wird zuerst angewendet, dann decorator_one.lru_cachefrom functools import lru_cache
@lru_cache
def fibonacci(n):
if n in (0, 1):
return n
return fibonacci(n - 1) + fibonacci(n - 2)
lru_cache speichert bereits berechnete Ergebnisse im Cache.| Konzept | Nutzen |
|---|---|
| Closures | Zustand bewahren, Daten kapseln |
| Lambda | Kürzere anonyme Funktionen |
| Higher-Order Funcs | Flexible Funktionskomposition |
| map/filter/reduce | Funktionale Verarbeitung von Listen |
| Partial Functions | Vorbelegte Funktionen |
| Decorators | Funktion erweitern ohne Quellcode zu ändern |