Eine Funktion ist ein Codeblock, der nur ausgeführt wird, wenn er aufgerufen wird, was bei rekursiven Funktionen auch durch sich selbst sein kann. Man kann beliebige Daten, sogenannte Parameter, an eine Funktion übergeben und diese kann wieder Daten zurückgeben.
Definition einer Funktion
In Python wird eine Funktion über die Anweisung def
definiert:
# Hinweis def my_function(): print("Hello from a function")
Aufruf einer Funktion
Auch wenn eine Funktion keine Parameter erwartet, muss sie mit runden Klammern aufgerufen werden; die Parameterliste ist dann einfach leer.
def my_function(): print("Hello from a function") my_function()
Parameter
Informationen können als Parameter an Funktionen übergeben werden. Diese werden nach dem Funktionsnamen als komma-separierte Liste in runden Klammern angegeben. Die Zahl der Parameter ist formal nicht begrenzt. Das folgende Beispiel hat eine Funktion mit einem Argument (fname). Wenn die Funktion aufgerufen wird, geben wir einen Vornamen weiter, der innerhalb der Funktion verwendet wird, um den vollständigen Namen zu drucken. Die hier definierte Funktion hat keinen Rückgabewert:
def my_function(fname): print(fname + " Mauser")# Einrückung beachten my_function("Johnny") my_function("Maxi") my_function("Linus")
In Python Dokumentationen wird statt von Parametern oft von Argumenten gesprochen, die in Syntaxdiagrammen
oft mit args abgekürzt werden. Formal bezeichnet man auch die Werte beim Aufruf einer Funktion als
Argumente, in der Funktion selbst aber als Parameter. Dies ist nicht ganz unwichtig, denn ein Aufruf
einer Funktion mit myFunc(1/2)
führt dazu, dass das Argument 1/2 in der Funktion selbst dann 0.5 ist.
Kurzum: Für einen Programmieranfänger in Sachen Python ist dieser Unterschied nicht weiter von Belang.
Anzahl der Argumente
Standardmäßig muss eine Funktion mit der richtigen Anzahl von Argumenten aufgerufen werden. Das heißt, wenn eine Funktion zwei Parameter erwartet, muss sie auch mit zwei Argumenten aufgerufen werden, nicht mehr und nicht weniger. Es ist sondt mit einem Fehler zu rechnen.
def my_function(fname, lname): # zwei Parameter print(fname + " " + lname) my_function("Johnny", "Mauser") # zwei Argumente #my_function("Johnny", "von", "Mauser") # drei Argumente -> Fehler
Beim Aufruf mit drei Argumenten lautet die Fehlermeldung:
# Hinweis TypeError: my_function() takes 2 positional arguments but 3 were given
Beliebige Argumente durch *args
Wenn man nicht vorab weiß, wieviel Argumente an die Funktion übergeben werden, fügt man in der Funktionsdefinition einen Stern * vor dem Parameternamen ein
(in Dokumentationen als *args
gekennzeichnet).
Auf diese Weise erhält die Funktion einen Tupel von Argumenten und kann entsprechend auf die Elemente zugreifen:
def my_function(*kids): # kids print("The youngest child is " + kids[2]) my_function("Emil", "Tobias", "Linus") my_function("Johnny", "Franz", "Linus", "Waldemar")
Key-Value - Argumente
Die sogenannte Key-Value-Syntax wird ebenso unterstützt und ist insbesondere für Anfänger eine interessante Alternative, da in jedem Fall klar ist, welcher Wert welcher VAriablen zugeordnet wird. Die Reihenfolger der Angabe spielt dadurch keine Rolle mehr.def my_function(child3, child2, child1): print("The youngest child is " + child3) my_function(child1 = "Emil", child2 = "Tobias", child3 = "Linus")
In Dokumenmtationen wird diese Art der Parameterüberagbe oft mit kwargs
(keyword arguments) bezeichnet.
Beliebige Zahl an Key-Value - Argumenten mit **kwargs
Wenn die Zahl der Schlüsselwortargumente, die an die Funktion übergeben werden, nicht konstant ist,
so kann man dies durch zwei Sternchen (**
) vor dem Parameter verdeutlichen. Die übergebenden
Argumente werden dann als Wörterbuch (dictionary) an die Funktion übergeben und können dort entsprechend
benutzt werden. In Dokumentationen werden sie oft zu **kwargs
abgekürzt.
def my_function(**kid): print("His last name is " + kid["lname"]) my_function(fname = "Johnny", lname = "Mauser") my_function(fname = "Johnny", lname = "Mauser", foo = "bar", x = "y")
Standardwerte bei fehlenden Parametern
Immer dann, wenn ein Parameter einen Wert haben soll, die Funktion aber ohne einen entsprechendes Argument aufgerufen wurde, ist es sinnvoll, dafür Standardwerte festzulegen (default).
def my_function(country = "Norway"): print("I am from " + country) my_function("Sweden") my_function("India") my_function() my_function("Brazil")
Eine Liste als Argument
Es wurde bereits erwähnt, dass es faktisch keine Einschränkung bei der Art der Argumente gibt; Strings, Zahlen, Listen, Dictionaries, usw., sind alle möglich.
def my_function(food): for x in food: print(x) fruits = ["apple", "banana", "cherry"] my_function(fruits)
Return Values
Für die Rückgabe von Werten gilt das gleiche wie für die Parameter: Alle Typen sind möglich und müssen als Argument derreturn
Anweisung mitgegegeben werden::
def my_function(x): return 5 * x print(my_function(3)) print(my_function(5)) print(my_function(9))
pass
Statement
Wie schon im Abschnitt Schleifen erwähnt, kann der Fall auftreten, dass man bei der Programmentwicklung sehr wohl Vorstellungen vom Aufruf der
Funktion hat, nicht jedoch vom eigentlichen Inhalt. Da eine Funktion aber mindestens eine Anweisung enthalten muss,
kann man wieder mit dem pass
statement arbeiten, um Fehler zu vermeiden:
# Hinweis def myfunction(): pass
Global -- lokal
y = 20 # Global definiert def funktion(): z = 30 # lokal in der Funtkion x = 33 # " " " " y = z+x # " " " " global y2 y2 = 7 return locals() print(funktion(),y,y2)
Callable function
Ein aufrufbares Objekt ist alles, was mit Klammern aufgerufen wird.
Die Klammern können Argumente enthalten. Callable Objekte verhalten sich im Wesentlichen wie
Funktionen und können ausgeführt werden, um eine Aktion auszuführen.
Die integrierte Funktion callable()
verwendet ein Objekt als Argument und
gibt einen booleschen Wert zurück, der angibt, ob das Objekt aufrufbar ist oder nicht.
str_ = "Wie schön ist Panama" def Hallo(name): return ("Hallo " + name + "!") print(callable(Hallo),Hallo("Johnny Mauser")) print(callable(str_))
Rekursion
In Python sind auch Funktionsrekursionen möglich, d.h. eine Funktion ruft sich selbst wieder auf.
Die Rekursion ist ein gängiges Komzept für die Mathematik und das Programmieren, beispielsweise
die Berechnung einer Fakultät.
Allerdings ist dabei Vorsicht geboten, denn es kann sehr schnell zu einer endlosen Schleife kommen,
die dann in der Regel mit einem Speicherüberlauf abbricht.
Bei korrekter Anwendung sind Rekursionen jedoch ein sehr effizienter und mathematisch eleganter Ansatz
für die Programmierung.
Im folgenden ein einfaches Beispiel ist tri_recursion()
eine Funktion, die sich selbst wieder aufruft ("recurse").
Die Variable k, die der Funktion übergeben wird, wird dabei jedesmal dekrementiert (-1).
Die Rekursion endet, wenn die Bedingung nicht größer als 0 ist, beziehungsweise k=0 gilt.
Für einen neuen Entwickler kann es einige Zeit dauern, um herauszufinden, wie genau dies funktioniert.
def tri_recursion(k): if(k > 0): result = k + tri_recursion(k - 1) # _lokales_ k bleibt gespeichert print(result) # wird erst erreicht, wenn das nächste tri-Recursion ein return(result) hat else: result = 0 # erste Wertzuordnung da jetzt k=0 sein muss return result # Wert von result zurückgeben print("\n\nRecursion Example Results") tri_recursion(6) """ Erklärung: 1. Aufruf mit k=6 k>0 JA result = 6 + tri_recursion(5) # Funktion ruft sich selbst auf (1) 2. Aufruf mit k=5 k>0 JA result = 5 + tri_recursion(4) # Funktion ruft sich selbst auf (2) 3. Aufruf mit k=4 k>0 JA result = 4 + tri_recursion(3) # Funktion ruft sich selbst auf (3) 4. Aufruf mit k=5 k>0 JA result = 3 + tri_recursion(2) # Funktion ruft sich selbst auf (4) 5. Aufruf mit k=2 k>0 JA result = 2 + tri_recursion(1) # Funktion ruft sich selbst auf (5) 6. Aufruf mit k=1 k>0 JA result = 1 + tri_recursion(0) # Funktion ruft sich selbst auf (6) 7. Aufruf mit k=0 k>0 NEIN! result = 0 Rücksprung zu 6. mit return(0) 6. result = k + return-Wert # k jetzt wieder auf dem Wert von (6) = 1 + 0 = 1 Rücksprung zu 5. mit return(1) 5. result = k + return-Wert # (5) = 2 + 1 = 3 Rücksprung zu 4. mit return(3) 4. result = k + return-Wert # (4) = 3 + 3 = 6 Rücksprung zu 3. mit return(6) 3. result = k + return-Wert # usw. = 4 + 6 = 10 Rücksprung zu 2. mit return(10) 2. result = k + return-Wert = 5 + 10 = 15 Rücksprung zu 1. mit return(15) 1. result = k + return-Wert = 6 + 15 = 21 Rücksprung ins Hauptprogramm return(21) ENDE """
Lambda Operator (Funktion)
Eigentlich hat diese Art der Definition einer Funktion nichts mit Python zu tun, da sie eigentlich aus der funktionalen Programmierung (Lisp, Haskell, Miranda, ...) kommt. Mit Hilfe des Lambda-Operators können anonyme (namenlose) Funktionen erzeugt werden. Sie haben eine beliebe Anzahl von Parametern, führen einen Ausdruck aus und liefern den Wert dieses Ausdrucks zurück.
from math import pi squared = lambda x: x ** 2 # erwartet _einen_ Parameter ringarea = lambda r1, r2: pi * (squared(r1) - squared(r2)) # erwartet _zwei_ Parameter print("Der Kreisring mit den Radien 7cm und 3cm hat eine Fläche von "+str(ringarea(7,3))+" cm^2")
Anonyme Funktionen sind insbesondere bei der Anwendung der map
-, filter
- und reduce
-Funktionen von großem Vorteil.
Celsius = [39.2, 36.5, 37.3, 37.8] print("Celsius: ", Celsius) Fahrenheit = list(map(lambda x: 9/5*x + 32, Celsius)) print("Fahrenheit: ", Fahrenheit) C = list(map(lambda x: 5/9*(x-32), Fahrenheit)) # map kann nicht direkt ausgegeben werden print("Celsius: ", C) print("Celsius: ", end="") list(map(lambda x: print("{:6.1f}".format(x),end=""),C))
Built-in Funktionen
Der Python-Interpreter hat einige fest eingebaute Funktionen, auf die man ohne zusätzliche Module zugreifen kann.
Eine längere Abhandlung zu den Built-In functions gibt es hier.
Built-in Functions | |||
---|---|---|---|
Zusammenfassende Betrachtung
Standard-Argumente
In Python sind Standardargumente die Werte, die einem Funktionsparameter automatisch zugewiesen werden, wenn beim Funktionsaufruf kein Argument angegeben wird. Dadurch kann eine Funktion mit weniger Argumenten als angegeben aufgerufen werden. Standardargumente werden in der Funktionsdefinition angegeben und werden typischerweise verwendet, um einen Standardwert für ein optionales Argument bereitzustellen.
Im folgenden Beispiel erstellen wir eine Funktion mit zwei Parametern und übergeben dem Parameter "gender" ein Standardargument namens "unbekannt". Wenn wir die Funktion aufrufen und kein Argument an den Parameter "gender" übergeben, verwendet die Funktion das in der Funktionsdefinition angegebene Argument "unknown". Wenn wir die Funktion aufrufen und ein Argument für den Gender-Parameter angeben, verwendet die Funktion das übergebene Argument.
def personal_info(name, gender="Unknown"): return(f'{name}: {gender}') print(personal_info("Johnny")) print(personal_info("Johnny", "male"))
Positionale Argumente (Nicht-Schlüsselwort-Argumente)
Wenn Sie in Python eine Funktion aufrufen und Argumente angeben, die auf der Position der Parameter basieren, werden die Argumente als Positionsargumente bezeichnet. Im folgenden Code haben wir eine Funktion mit zwei Parametern erstellt: name und age. Wenn wir die Funktion aufrufen, geben wir Argumente auf der Grundlage der Reihenfolge oder Position der Parameter an. Wir übergeben den Namen Johnny als erstes Argument, weil der Name der erste Parameter und das Alter der zweite Parameter ist. Grundsätzlich werden also Positionsargumente mit Parametern auf der Grundlage ihrer Position verknüpft. Positionsargumente werden manchmal auch als "Nicht-Schlüsselwortargumente" bezeichnet.def personal_info(name, age): return(f'{name}: {age}') print(personal_info("Johnny", 9))
Schlüsselwort-Argumente
Wenn wir nun die Funktion aufrufen und dem Parameter explizit ein Argument zuweisen, werden die Argumente als Schlüsselwortargumente bezeichnet. Bei Schlüsselwortargumenten spielt die Reihenfolge, in der wir die Argumente übergeben, keine Rolle, da wir die Argumente ausdrücklich der Variablen zuweisen. Siehe das folgende Beispiel:
def personal_info(name, age): return(f'{name}: {age}') print(personal_info(age=9, name="Johnny"))
*args (Nicht-Schlüsselwortargumente)
Wenn in Python *args als Funktionsparameter übergeben wird, bedeutet dies, dass die Funktion eine beliebige Anzahl von Positionsargumenten annehmen kann. Das * vor dem Parameternamen in der Funktionsdefinition erlaubt es der Funktion, eine beliebige Anzahl von Positionsargumenten zu akzeptieren, die in einem Tupel gespeichert werden. Sie können einen beliebigen Namen als Parameternamen wählen, solange Sie * vor dem Namen verwenden. Es ist jedoch üblich, *args zu verwenden und Sie sollten sich an diese Konvention halten.
Im Folgenden erstellen wir eine Funktion, die eine beliebige Anzahl von Positionsargumenten annehmen kann. In beiden Fällen (9 Argumente bzw, 2 Argumente) gibt unsere Funktion den Durchschnitt der Argumente zurück.
def mittelwert(*args): mittelwert = sum(args)/len(args) return(mittelwert) print(mittelwert(1,2,3,4,5,6,7,8,9)) print(mittelwert(101,2002))
**kwargs (Schlüsselwortargumente)
Wenn wir **kwargs als Funktionsparameter übergeben, bedeutet dies, dass unsere Funktion eine beliebige Anzahl von Schlüsselwortargumenten annehmen kann. Das ** vor dem Parameternamen in der Funktionsdefinition ermöglicht es der Funktion, eine beliebige Anzahl von Schlüsselwortargumenten zu akzeptieren. Die Argumente werden in einem Dictionary gespeichert. Gemäß der Konvention müssen Sie "kwargs" als Parametername verwenden.
def mittelwert(**kwargs): mittelwert = sum(kwargs.values())/len(kwargs) return(mittelwert) print(mittelwert(ich=12,und=22,du=33)) print(mittelwert(er=101,sie=2002))
Next Lesson: 05 Dateien lesen und schreiben