7. Funktionen II

Wir können auch eigene Funktionen definieren:

>>> def readAndPrintLower():
...     s = raw_input()
...     print s.lower()
...

Eine Funktionsdefinition wird also mit def eingeleitet, dann kommt ein Name (wie Variablenname), dann Klammern und ein Doppelpunkt. Anschließend kommen Anweisungen, alle gleich weit eingerückt (wie weit, ist Geschmackssache. Vorerst empfehle ich, jeweils vier Spaces weit einzurücken.

Grundsätzlich schreibt Python schon in der Sprache relativ viel “code layout” vor. Trotzdem gibt es Konventionen, wie man Code zu schreiben sollte, um es anderen Menschen leichter zu machen. Autoritativ ist hier PEP 008, das ihr jetzt schon mal überfliegen solltet. Die Empfehlungen darin sind nicht entscheidend dafür, dass der Rechner mit eurem Code zurechtkommt, wohl aber dafür, dass routinierte Pythonistas ihn schnell und einfach lesen können. Haltet euch dran, und lest den Text nochmal nach dem Ende dieses Kurses.

Ausnahme: Die Empfehlung, Methodennamen mit underscores zu konstruieren (foo_bar statt fooBar) ist Mist. Ich werde sie in diesem Kurs ignorieren, und mein Tipp ist, dass ihr das ähnlich haltet. .

Die beiden Anweisungen bilden ein compound statement (eine Verbundanweisung). Sie endet, wenn wieder “ausgerückt” wird. Compound statements sind sozusagen die Nebensätze von Programmiersprachen: In ihnen wird eine Sequenz von zusammengehörigen Anweisungen zusammengefasst, die dann syntaktisch eine Anweisung bilden. Bei Funktionen ist noch nicht wirklich gut zu sehen, wie das funktioniert und wozu das gut ist, klarer wird das in Verbindung mit Selektion und Iteration.

Solange wir ein compound statement eingeben, gibt der Interpreter statt des normalen Prompts (>>>) drei Punkte aus.

Die Funktion können wir wie eingebaute Funktionen aufrufen:

>>> readAndPrintLower()
HaCk3rZ
hack3rz

Funktionen haben im Allgemeinen Argumente und geben einen Wert zurück. Das wird so definiert:

>>> def incString(s):
...     i = int(s)
...     i = i+1
...     return str(i)
...
>>> incString("5")
'6'

Das Argument kommt also in die Klammern, das reservierte Wort return steht vor dem, was zurückgegeben wird (und beendet die Funktion).

Reservierte Wörter, von denen es in Python gegen 30 gibt, sind eine Besonderheit. In Python können fast alle Namen mit neuen Bedeutungen belegt werden, insbesondere auch die Namen der eingebauten Funktionen (Falle!):

>>> int = 4
>>> int("35")
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
TypeError: 'int' object is not callable

Bei den reservierten Wörtern geht das nicht, sie sind aus Sicht des Sprachdesigners gleichgestellt mit Operatoren wie + und - oder auch Klammern und Leerzeichen:

>>> return = 4
  File "<string>", line 1
    return = 4
           ^
SyntaxError: invalid syntax

For the record, die reservierten Wörter von Python sind zur Zeit:

and       del       for       is        raise
assert    elif      from      lambda    return
break     else      global    not       try
class     except    if        or        while
continue  exec      import    pass      yield
def       finally   in        print

Wer versucht, reservierte Wörter als Variablennamen zu verwenden, wird, wie oben gezeigt, mit Syntaxfehlern bestraft.

Die Funktion “inkrementiert” eine Zahl, die in einem String steht. Wir jonglieren hier mit verschiedenen Typen. Addition von Strings und Zahlen geht nicht.

>>> "4"+1
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
TypeError: cannot concatenate 'str' and 'int' objects

Die Funktion wehrt sich, wenn man von ihr etwas will, für das wir sie nicht geschrieben haben:

>>> incString("bla")
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
  File "<stdin>", line 2, in incString
ValueError: invalid literal for int(): bla

Wir werden bald sehen, was man tun kann, um solche Fehlermeldungen (stack trace) zu vermeiden oder Fehlerbedingungen sinnvoll zu behandeln.

Ein weiterer interessanter Aspekt der Funktion ist das i = i+1. Mathematisch ist das blanker Unsinn. Für Python bedeutet diese Anweisung aber:

  1. Zuweisung! Sehen wir erstmal die rechte Seite an.
  2. Die rechte Seite ist ein Ausdruck – das können wir berechnen.
  3. Wir nehmen den Wert von i, addieren eins drauf und haben jetzt einen Wert
  4. So, wir haben einen Wert, und wir waren am Zuweisen – was steht also auf der linken Seite? Oh, i zuweisen, lassen wir also jetzt i auf den berechneten Wert zeigen. Das, worauf i vorher gezeigt hat, interessiert nicht mehr.

Übungen zu diesem Abschnitt

Ihr solltet euch wenigstens an den rötlich unterlegten Aufgaben versuchen

(1)

Probiert die Funktion incString aus. Schreibt sie so um, dass sie ihr Argument um 5 erhöht. Was passiert, wenn ihr das int weglasst? Warum?

(2)

Schreibt eine Funktion decString, die eine in einen String verpackte Zahl nimmt, eins von der Zahl abzieht und das Ergebnis wieder als String zurückgibt.

(3)

Macht euch den Unterschied zwischen reservierten Wörtern und eingebauten Funktionen klar. Probiert folgendes aus und erklärt die Fehlermeldungen, die ihr seht (oder nicht seht):

>>> return = 1
>>> int = return
>>> raw_input = 2
>>> b = raw_input("Anzahl: ")
>>> raw_input = int
>>> raw_input("123")

(4)

Macht euch klar, wie i = i+1 funktioniert, etwa, indem ihr beobachtet, was bei einem Dialog passiert, in dem ihr folgendes tippt:

>>> i = 2
>>> i+1
>>> print i
>>> i = i+1
>>> print i


Markus Demleitner

Copyright Notice