Abstraktion von Ausdrücken durch Funktionen

Maximum zweier Zahlen

Einen Ausdruck zur Berechnung des Maximums zweier Zahlen können wir zum Beispiel wie folgt als Funktion abstrahieren:

def max(x, y):
  if x > y:
    z = x
  else:
    z = y
  return z

Das Schlüsselwort def leitet die Funktionsdefinition ein, max ist der Name der definierten Funktion und die Variablen x und y heißen formale Parameter der Funktion max. Der sogenannte Funktionsrumpf enthält die bedingte Anweisung zur Berechnung des Maximums z der Werte von x und y. In der letzten Zeile wird mit Hilfe des Schlüsselwortes return der Wert von z als Rückgabewert der Funktion max festgelegt.

Eine Rückgabe-Anweisung mittels return beendet die Ausführung des Funktionsrumpfes auch dann, wenn sie nicht an dessen Ende steht. Wir können deshalb die Funktion max auch etwas kürzer wie folgt definieren:

def max(x, y):
  if x > y:
    return x
  else:
    return y

Wenn wir diese Funktion in einem Python-Programm maxFun.py speichern, können wir es wie folgt in die interaktive Python-Shell einbinden und ausführen:

>>> from maxFun import *
>>> max(2,3)
3
>>> 

Die import-Anweisung bewirkt also, dass max() als eine vordefinierte Funktion verwendet werden kann.

Um das Maximum dreier Zahlen zu berechnen, können wir nun statt einer geschachtelten bedingten Anweisung geschachtelte Funktions-Aufrufe verwenden:

>>> from maxFun import *
>>> max(1,max(3,2))
3
>>> 

Bei der Auswertung eines Funktionsaufrufes werden zunächst die Argumente (auch aktuelle Parameter genannt) ausgewertet und dann in den Funktionsrumpf eingesetzt. Wir können die Auswertungsreihenfolge sichtbar machen, indem wir Ausgaben in den Funktionsrumpf einbauen:

def max(x, y):
  print('Aufruf: max(' + str(x) + ', ' + str(y) + ')')
  if x > y:
    print('Rückgabewert: ' + str(x))
    return x
  else:
    print('Rückgabewert: ' + str(y))
    return y

Nachdem wir das Programm mit der import-Anweisung neu geladen haben, können wir den obigen Ausdruck mit den eingefügten Ausgaben auswerten:

>>> from maxFun import *
>>> max(1, max(2, 3))
Aufruf: max(2, 3)
Rückgabewert: 3
Aufruf: max(1, 3)
Rückgabewert: 3
3

Hierbei erkennen wir, dass zunächst der Aufruf max(2, 3) zu 3 ausgewertet wird. Danach wird dieses Ergebnis als Argument des äußeren Aufrufs von max verwendet. Der Aufruf max(1, 3) wird dann zu 3 ausgewertet.

Ausgaben wie hier sind oft nützlich zur Fehlersuche in Programmen. Zugunsten einer Trennung von Ausdrücken und Anweisungen sollte aber in Funktionen in der Regel auf Ausgaben verzichtet werden.

Beachten Sie den Unterschied zwischen Ausgabe-Anweisungen zur Ausgabe eines Wertes im Terminal und Rückgabe-Anweisungen zur Festlegung des Rückgabewertes von Funktionen. Eine Ausgabe-Anweisung legt keinen Rückgabewert fest und eine Rückgabe-Anweisung erzeugt keine Ausgabe im Terminal!

Primzahltest

Als weiteres Beispiel für Abstraktion durch Funktionen betrachten wir die Aufzählung aller Primzahlen bis zu einer gegebenen Obergrenze. Wenn wir den Primzahltest als Funktion is_prime(n) abstrahieren, können wir ihn in einer Wiederholung mit fester Anzahl aufrufen, statt die Definition des Tests in die Wiederholung zu kopieren.

def is_prime(n):
  teilbar = False
  k = 2
  while not teilbar and k*k <= n:
    teilbar = (n % k) == 0
    k = k + 1
  return(n > 1 and not teilbar)

max = 100
for i in range(2,max+1):
  if is_prime(i):
    print(i)

Die Funktion is_prime() liefert einen Wahrheitswert zurück und wird deshalb auch Prädikat genannt. Es ist eine Konvention, die Namen von Prädikaten wie Fragen zu formulieren. Prädikate in Python werden oft mit dem Präfix is_ benannt. Dies ist nicht vorgeschrieben, erhöht aber die Lesbarkeit.

Das definierte Prädikat is_prime() wird in einer Zählschleife nach seiner Definition aufgerufen. Sein Ergebnis wird mit einer bedingten Anweisung überprüft um alle Primzahlen zwischen 2 und max auszugeben.

Funktionen müssen in Python vor ihrem ersten Aufruf definiert werden.