Dictionary | Python-Kurs | Klassen |
- Definition einer Funktion
- Parameter
- Parametertypen prüfen
- Vorbelegte Parameter
- Parameter per Namen belegen
- Variable Anzahl von Funktionsparametern
- Rückgabewert
- Doc-Strings
- Globale und lokale Variablen
- Rekursion
- Übungsaufgaben
- Video
# zähle bis 10 for i in range(1,11,1): print(i) ... # zähle bis 10Statt hier die beiden Zeilen erneut einzuippen oder zu kopieren, definieren wir eine Funktion und rufen sie zwei Mal auf.
Definition einer Funktion
def zaehleBis10(): for i in range(1,11,1): print(i) ... zaehleBis10() ... zaehleBis10()Funktionen ermöglichen es, aus mehreren Befehlen einen neuen Befehl zusammenzusetzen.
- Vor dem ersten Aufruf muss sie mit def definiert werden.
- Jede Funktion benötigt einen eigenen, eindeutigen Namen. Der wird hinter dem def genannt und über diesen wird die Funktion aufgerufen.
- Ein besonderes Merkmal der Funktion sind die runden Klammern hinter dem Namen. Derzeit enthalten sie nichts, aber das werden wir noch ändern.
- Am Ende der def-Zeile erscheint ein Doppelpunkt und alles, was zur Funktion gehört wird eingerückt. Das kennen Sie schon von Abfragen und Schleifen.
- Egal, wo im Code die Funktion gerufen wird, kehrt der Interpreter nach Beendigung der Funktion zu der Stelle zurück, wo der Aufruf herkam. Keine Sorge, der Interpreter findet immer den richtigen Ort.
Etwas speziell: Funktionsvariablen
Wenn man den Namen einer Funktion ohne Klammern verwendet, wird nicht etwa die Funktion aufgerufen, sondern sie liefert die Stelle, an der die Funktion definiert wurde, also deren Adresse.Diese Adresse kann wiederum einer anderen Variablen zugewiesen werden, die dann ebenfalls die Adresse der Funktion enthält.
Hängt man dieser Variablen nun ein paar Klammern an, wird die Funktion aufrufen, deren Adresse sie enthält.
Im Augenblick scheint das eher Quatsch zu sein, aber es gibt tatsächlich praktische Anwendungen dafür, beispielsweise, wenn Funktionen als Parameter für einen Rückruf übergeben werden sollen.
def zaehleBis10(): for i in range(1,11,1): print(i) anders = zaehleBis10 anders() # ruft die Funktion zaehleBis10
Lokale Variablen
In der Funktion zaehleBis10 wird übrigens die Variable i verwendet. Diese Variable bleibt nach außen unsichtbar in der Funktion. Ein Zugriff von außen ist nicht möglich. Man spricht von lokalen Variablen.Nicht einmal dann, wenn man außerhalb der Funktion eine Variable gleichen Namens verwendet, wird sie durch die Variable in der Funktion verändert.
>>> i = 4 >>> print(i) 4 >>> zaehleBis10() 1 2 ... 10 >>> print(i) 4
Parameter
Bisher hat unsere Funktion immer genau bis 10 gezählt. Aber vielleicht will man an der einen Stelle im Programm bis 5 zählen und an der nächsten bis 7. Damit wir deshalb nicht schon wieder überflüssigen Code mehrfach verwenden, ist es möglich, der Funktion mitzuteilen, bis wohin sie zählen soll. Das erreicht man mit einer Parametervariablen, die man zwischen die Klammern setzt.def zaehle(ende): for i in range(1,ende+1,1): print(i)Beim Aufruf wird nun die gewünschte Zahl zwischen die Zähne, sorry - zwischen die Klammern genommen.
zaehle(5) zaehle(7)In der ersten Zeile wird die 5 in die Parametervariable ende kopiert. Die Funktion zählt nun also bis 5. Beim zweiten Aufruf kommt eine 7 zwischen die Klammern. Beim Start der Funktion findet die Funktion zaehle also die 7 in der Variablen ende und zählt bis 7.
Was mit festen Zahlen funktioniert, funktioniert natürlich auch mit Variablen. Der folgende Aufruf wird zaehle also bis 8 zählen lassen.
anzahl = 8 zaehle(anzahl)Die Funktion kann den Parameter ende wie eine Variable verwenden. Hier wird der Parameter als Variable ende an den Aufruf von range() weitergereicht, um das Ende frei gestalten zu können.
Parametertypen prüfen
Parameter können vom Aufrufer frei belegt werden. Dumm nur, wenn statt der erwarteten Zahl ein Text übergeben wird. Python ist das zunächst egal, weil Variablen ja beliebige Typen aufnehmen können. Aber es wird schon etwas schwierig, wenn man bis zu seinem eigenen Vornamen zählen soll.Um solche Probleme zu verhindern, kann man den Typ einer Variablen mit der Funktion type prüfen.
def zaehle(ende): if type(ende) in (float, int): for i in range(1, ende+1, 1): print(i) else: print("nix")Im unserem Fall wird geprüft, ob der Typ float oder int ist. Damit kann man wunderbar zählen. Falls doch ein Text oder sonst etwas Merkwürdiges übergeben wurde, gibt die Funktion einfach nix aus.
>>> zaehle(3) 1 2 3 >>> zaehle('Hallo') nix
Vorbelegte Parameter
Sie können die Parameter einer Funktion bei der Definition vorbelegen. Das ist praktisch, wenn bestimmte Werte nur selten verändert werden sollen.Alle vorbelegten Parameter müssen beim Aufruf nicht zwingend angegeben werden. Sie erhalten dann eben den vorbelegten Wert. Die Funktion zaehle() wird nun so verändert, dass der Schritt beim Zählen als weiterer Paramter angegeben werden kann. Ansonsten wird eine Schrittweite von 1 angenommen.
def zaehle(ende, schritt=1): for i in range(1,ende+schritt,schritt): print(i)Der erste Aufruf übergibt lediglich eine 3 und wird darum bis 3 zählen und dabei immer um 1 erhöhen. Im zweiten Aufruf soll bis 5 gezählt werden, aber dieses Mal immer um 2 erhöht werden.
>>> zaehle(3) 1 2 3 >>> zaehle(5, 2) 1 3 5
Parameter per Namen belegen
Beim Aufruf einer Funktion werden die Parameter von links nach rechts belegt, so wie es bei der Funktionsdefinition festgelegt wurde. Wenn Funktionen aber sehr viele Parameter haben, insbesondere, wenn sie zu einem großen Teil vorbelegt sind, kann es praktisch sein, nur einzelne Parameter zu verwenden und diese zu benennen.Dazu wird in der Klammer des Funktionsaufruf eine Zuweisung des Wertes an den Parameternamen durchgeführt.
Schauen wir auf diese Version von zaehle:
def zaehle(start=1, ende=10, schritt=1): for i in range(start,ende+schritt,schritt): print(i)Prinzipiell müssen nicht alle Parameter vorbelegt sein. Die nicht belegten müssen allerdings zuerst aufgezählt sein und auf jeden Fall in der richtigen Reihenfolge aufgerufen werden.
Die obige Funktion kann beispielsweise so aufgerufen werden:
>>> zaehle(ende=3) 1 2 3 >>> zaehle(1, 5, schritt=2) 1 3 5Da der Name angesprochen wird, kann die Reihenfolge der Parameter egal sein. Durch diese Aufrufmethode wird gleichzeitig dokumentiert, welche Parameter gemeint sind. Das ist bei mehreren Parametern durchaus hilfreich. Beispiel:
termin(12,5)Ist der Termin nun am 12.5. oder nach amerikanischer Lesart am 5.12.? Die Nennung der Parameternamen bringt Klarheit.
termin(monat=12,tag=5)Nun ist es auch egal, ob der Programmierer der Funktion termin den tag oder den monat als ersten Parameter verwendet hat.
Variable Anzahl von Funktionsparametern
Mithilfe von Tupeln können Sie Funktionen eine variable Anzahl von Parametern verleihen. Die einfachste Version dies zu realisieren, ist dass Sie ein Tupel als Parameter verwenden. Im folgenden Beispiel ist der erste Parameter noch fest. Erst ab dem zweiten wird ein Tupel übergeben.def calltupel(fest, tupelparameter): print(fest) for element in tupelparameter: print(element) calltupel(12, (1, "Schau an", 3))Sie müssen beim Aufruf natürlich darauf achten, dass die variablen Parameter in extra Klammern eingeschlossen sind, sonst meldet sich der Interpreter mit der Meldung, dass er deutlich weniger Parameter erwartet hatte.
Die andere Variante besteht darin, dass Sie die Tupel-Auflösung im Funktionskopf durchführen und einen Stern vor den Parameter setzen.
def tumehr(fest, *parameter): print(fest) # nicht ueberraschend for element in parameter: print(element) tumehr("Fest", 12, "locker")
Rückgabewert
Eine mathematische Funktion liefert immer einen Wert zurück. Das kann eine Funktion in Python auch. Dazu muss am Ende der Funktion lediglich ein Wert mit dem Befehl return zurückgegeben werden.def summiere(ende): summe = 0 for i in range(1,ende+1,1): summe += i return summe Summe = summiere(10) print(summiere(3))Die Variable Summe wird durch den Rückgabewert der Funktion summiere() initialisiert.
Wird eine Funktion nicht mit return abgeschlossen, wird automatisch return None hinzugefügt.
Rückgabe mehrerer Werte
Eine Funktion liefert, wie oben gesagt, immer einen Wert zurück. Manchmal möchte man mehrere Werte zurückgeben. Das funktioniert bei Python deshalb recht einfach, weil nicht nur eine Variable, sondern auch ein Tupel zurückgegeben werden kann.Stehen hinter dem Befehl return mehrere Werte, die durch Komma getrennt sind, interpretiert Python diese sofort als Tupel.
def gibMalEinDatum(): return 28,12,1998Nun kann man die Rückgabe in einer Variable speichern, die von Python sofort als Tupel behandelt wird, oder aber man gibt drei Variablen kommasepariert auf die linke Seite des Zuweisungszeichens.
>>> datum = gibMalEinDatum() >>> print(datum) (28, 12, 1998) >>> tag, monat, jahr = gibMalEinDatum() >>> print(monat) 12Wies Sie sehen, können Sie die Bestandteile des Datums auch wieder zerlegen, indem Sie links neben das Gleichheitszeichen drei Variablen setzen. Je eine für den Tag, den Monat und das Jahr. Es müssen aber genau so viele Variablen sein, wie Elemente in dem Tupel existieren, sonst hustet Ihnen der Interpreter einen ValueError vor.
Doc-Strings
Um Methoden zu dokumentieren, kann man einen mehrzeiligen String mit drei Anführungszeichen einleiten. Dieser wird als Doc-String behandelt.def doppelt(wert): """Die Funktion verdoppelt den übergebenen Wert und gibt ihn zurück""" return wert*2In diesem Fall hat der Programmierer der Funktion doppelt in dem String eine Erläuterung beigefügt. Diese kann mit dem Aufruf von help mit dem Funktionsnamen als Parameter aufgerufen werden.
help(doppelt)Im Interpreter erscheint eine komplette Seite mit dem Funktionsnamen und dem Parameter gefolgt von dem Doc-String. Um diese Seite wieder zu verlassen, muss man die Taste Q drücken.
Globale und lokale Variablen
Variablen, die innerhalb einer Funktion initialisiert werden, sind außerhalb der Funktion nicht zugreifbar. Darum bezeichnet man sie als lokale Variablen.Wenn eine Funktion einer globalen Variablen einen Wert zuweisen will, dann entsteht ein Problem. Der Interpreter hält dies für das Anlegen einer lokalen Variablen. Die globale Variable bleibt unverändert.
summe = 0 def summiere(ende): summe = 0 for i in range(1,ende+1,1): summe += i summiere(10) print(summe) # Das Ergebnis ist 0!Das ist grundsätzlich auch ganz gut so. Denn grundsätzlich sollten die Werte, die von der Funktion verändert werden, über den Befehl return zurückgegeben werden und nicht per Seiteneffekt auf globale Variablen.
Andererseits kann es Situationen geben, in denen Sie unbedingt eine Variable außerhalb der Funktion verändern müssen. In diesem Fall können Sie sich helfen, indem Sie die Variale explizit als global deklarieren.
summe = 0 def summiere(ende): global summe # Verwende die globale Variable! summe = 0 for i in range(1,ende+1,1): summe += i summiere(10) print(summe) # Das Ergebnis ist nun 55!Parametervariablen sind ebenfalls lokale Variablen.
Rekursion
Rekursionen sind Funktionen, die sich selbst aufrufen. Dieses Werkzeug ist mächtig und in bestimmten Situationen unabdingbar. Eine ausführlichere Betrachtung befindet sich hier, allerdings sind dort die Beispielprogramme in Java und C gehalten.Da die Funktion nach ihrem Ablauf immer zu dem Punkt zurückkehrt, wo sie aufgerufen wurde, ist es auch möglich, dass sich die Funktion selbst aufruft. Prinzipiell ist das mit einer Schleife vergleichbar. Und wie bei einer Schleife ist es auch bei der Rekursion wichtig, darauf zu achten, dass es eine saubere Abbruchbedingung gibt.
Als einfaches Beispiel soll die rekursive Funktion zählen, allerdings zunächst rückwärts.
def zaehleRekursiv(bis): # rekursive Funktion if bis>0: # Endebedingung der Rekursion print(bis) # Aktion zaehleRekursiv(bis-1) # Selbstaufruf zaehleRekursiv(3)Die Funktion wird von außen mit dem Parameter 3 aufgerufen. Da dieser größer als 0 ist, wird er zunächst auf dem Bildschirm ausgegeben. Dann ruft sich die Funktion selbst auf und vermindert dabei den Zähler um 1. Die Funktion wird also mit 2 aufgerufen, gibt diese aus, ruft sich mit 1 auf, gibt diese aus und ruft sich schließlich mit 0 auf.
Nun aber wird die Abfrage verhindern, dass sich die Funktion selbst aufruft. Stattdessen tut sie nichts weiter und kehrt zu ihrem Selbstaufruf zurück. Dort ist die Variable bis noch 1. Da aber kein Befehl mehr folgt, läuft die Funktion wieder auf ihr Ende, springt zurück zum Selbstaufruf. Dies wiederholt sich, bis die Funktion zu ihrem ersten Aufruf zurückkehrt, der außerhalb der Funktion liegt.
Um nun von 1 bis 3 zu zählen, müssen Sie den print()-Aufruf nur hinter den Selbstaufruf stellen. Dann nämlich ruft sich die Funktion immer wieder selbst auf, bis die Variable bis 0 ist. Sie kehrt dann hinter den Selbstaufruf zurück. Dort ist bis dann 1 und wird per print() ausgegeben. Wieder läuft die Funktion auf ihr Ende, springt hinter den Selbstaufruf und gibt eine 2 aus.
def zaehleRekursiv(bis): # rekursive Funktion if bis>0: # Endebedingung der Rekursion zaehleRekursiv(bis-1) # Selbstaufruf print(bis) # Aktion zaehleRekursiv(3)Sie werden zurecht darauf hinweisen, dass es viel einfacher ist, mit einer Schleife zu zählen. Dennoch sollten Sie sich die beiden Zählrekursionen genauer anschauen, bis Sie verstanden haben, warum sie so funktionieren.
Rekursionen können bestimmte Probleme und Datenstrukturen extrem gut bearbeiten. Ein typisches Beispiel ist das Durchlaufen von Baumstrukturen, wie es die Verzeichnisstruktur einer Festplatte darstellt.
Übungsaufgaben
Im Beispielprojekt Codeknacker wird gezeigt, wie man mit Funktionen einen Top-Down-Entwurf verfolgt.
Fakultät
Die Fakultät von n ist so definiert, dass alle Zahlen von 1 bis n miteinander multipliziert werden. Also ist die Fakultät von 3 das Ergebnis von 1 * 2 * 3, also 6. Die von 5 ist 1 * 2 * 3 * 4 * 5, was 120 ergibt.Dafür kann man eine Funktion schreiben, die n als Parameter übernimmt und das Ergebnis als Rückgabewert zurückgibt.
Größter gemeinsamer Teiler
Der ggT genannte größte gemeinsame Teiler ist die Zahl, durch die zwei andere teilbar sind, um genau zu sein, die größte davon. Diese Zahl ist beispielsweise beim Kürzen von Brüchen sehr nützlich.Ein schönes Verfahren wird bei den Übungsaufgaben für Schleifen dargestellt. Diese werden Sie vielleicht schon gelöst haben.
Nun sollen Sie eine Funktion schreiben, die die beiden Zahlen als Parameter entgegen nimmt und den ggT als Rückgabewert liefert. Der Aufruf könnte dann so lauten:
wert = ggT(42, 36)
Rekursive Fakultät
Falls Ihnen die Fakultät oben Spaß gemacht hat, können Sie diese ja einmal rekursiv ermitteln.Video