Link Search Menu Expand Document

Funktionen

Grundlagen

In Python kann man selbst Funktionen definieren. Das geht so:

def funktionsname(arg1, arg2 = 2):
    '''Doc-String: wird angezeigt, wenn die Hilfe
    help(funktionsname) aufgerufen wird.
    '''
    print('Die Funktion "funktionsname" wird ausgefuehrt')
    return arg1 * arg2

Mit return ... wird die Größe definiert, die anschließend als Wert der Funktion zurückgegeben wird. Wird kein Rückgabewert bei returndefiniert wird der Wert None zurückgegeben.

Argumente, die der Funktion übergeben werden, können einen Defaultwert haben, wie das bei arg2 der Fall ist.

So wird die Funktion aufgerufen:

funktionsname(2)
funktionsname(2, 4)
funktionsname(2, arg2 = 4)

Argumente

Werte die einer Funktion übergeben werden stehen in den runden Klammern nach dem Funktionsnamen.

Wird den Argumenten kein Default-Wert zugewiesen, erfolgt die Übergabe durch die Position der Argumente (positional arguments)

def pos_arg_fkt(arg1, arg2):
    return arg1 * arg2

pos_arg_fkt(1, 2) # hier wird arg1 = 1 und arg2 = 2
pos_arg_fkt(1, arg2=2) # ist auch erlaubt

pos_arg_fkt(arg1=1, 2) # syntax error!!

Man darf bei dieser Funktion auch Keywords benutzen, wichtig ist allerdings, dass niemals ein Positions-Argument nach einem Keyword-Argument kommt!

Das gilt auch für Funktionen mit Keyword-Argumenten (also Default-Werten:

def key_arg_fkt(arg1 = 1, arg2 = 2):
    return arg1 * arg2

key_arg_fkt() # hier wird arg1 = 1 und arg2 = 2
key_arg_fkt(arg2=4) # ist auch erlaubt

key_arg_fkt(arg1=2, 4) # syntax error!!

Man kann beide Arten auch mischen:

def mixed_arg_fkt(arg1, arg2 = 2):
    return arg1 * arg2

mixed_arg_fkt(1) # hier wird arg1 = 1 und arg2 = 2
mixed_arg_fkt(1, 2) # ist auch erlaubt

mixed_arg_fkt(arg2=4) # error: missing 1 required positional argument
mixed_arg_fkt(arg1=2, 4) # syntax error!!

Lokale und globale Variablen

Gewisse Funktionen in Python sollen immer verfügbar sein, z.B. id() oder type(). Diese Funktionen sind im built-in namespace zu finden. Variablen die innerhalb des “Hauptkörpers” des Programms definiert werden gehören zum global namespace. Alle Variablen, die in einer Funktion verändert oder zugewiesen werden, sind Teil des local namespace.

konstante = 42  #Variable "konstante" im global namespace

def f(x):
    konstante = 1 #Variable "konstante" im local namespace
    y = konstante*x
    return y

Das Ergebnis von f(1) ist 1, da die der Wert der lokalen konstante eins ist. Dabei wir die Variable konstante die vor der Funktionsdefinition steht nie verändert!

Im Folgenden Beispiel wird die Variable aus dem globalen Namenstraum innerhalb der Funktion benutzt.

konstante = 42

def f(x):
    global konstante
    y = x*konstante
    konstante =1
    return y

f(1)

Namespaces

Achtung: mutable und immutable

Wenn einer Funktion Argumente übergeben werden, so muss darauf geachtet werden, ob die Argumente mutable oder immutable sind.

funktion1 verändert die ihr übergebene Liste, funktion2 tut das ebenfalls und gibt ein ganz anderes Objekt zurück. funktion3 verändert die übergebene Liste nicht und gibt eine neue, abgeänderte Liste zurück.

from copy import copy

def funktion1(x):
    '''erwartet eine Liste'''
    x.append(4)
    print("f1 durchgefuehrt")

def funktion2(x):
    '''erwartet eine Liste'''
    x[1] = 'Huhn'
    x = 3.33  # ab hier verliert 'x' die Verbindung
    # zum übergebenen Objekt x
    print("f2 durchgefuehrt")
    return x

def funktion3(x):
    '''erwartet eine Liste'''
    y = copy(x)
    y.append('asdf')
    print("f3 durchgefuehrt")

Noch mehr zur Übergabe von Argumenten (optional)

Obligatorische Schlüsselwortargumente ohne Default-Wert

Bei den oben skizzierten Varianten der Übergabe von Argumenteen wurden diese entweder ohne Default-Wert nach ihrer Position übergeben oder mit Default-Werten über Schlüsselwörter. Es könnte aber wünschenswert sein, Argumente ohne Default-Wert über Schlüsselwörter zu übergeben.

Argumente ohne Default-Wert müssen tatsächlich übergeben werden, man kann sie nicht weglassen. In Python 3 geht das so:

def f(a,*,b,c=3):
   print("a: ",a)
   print("b: ",b)
   print("c: ",c)

Alle Argumente nach dem * müssen über ihr Schlüsselwort übergeben werden. Dabei kann man die Argumente mit Default-Wert (hier c) weglassen, b aber kann man nicht weglassen. Also z. B.

# Achtung! Nur Python 3

def integral(f, *, a, b, n=1000):
    '''Approximiert das Integral über f von a bis b nach der Trapezregel
    mit n Unterteilungen'''
    x = np.linspace(a, b, n+1)
    return (-0.5*f(a)-0.5*f(b)+np.sum(f(x)))*(b-a)/n
integral(np.exp, a=1, b=2, n=1000)  # geht
integral(np.exp, a=1, b=2) # geht auch
integral(np.cos, 1, 2, 1000)  # Fehler

Argumente ein- und auspacken

Durch Position bestimmte Argumente: Listen und Tupel übergeben

Eine beliebige Zahl von durch ihre Position bestimmten Argumenten kann verpackt werden in ein Tupel (oder eine Liste), bzw. ausgepackt werden aus einem Tupel oder einer Liste.

Syntax bei der Funktionsdeklaration mit Sternchen:

def f(*x):
    print("0. Arg: ", x[0])
    print("1. Arg: ", x[1])
    print("Rest: ", x[2:])
    print(type(x))

Durch Schlüsselwort bestimmte Argumente: Dictionaries übergeben

Eine beliebige Zahl von durch Schlüsselwort bestimmte Argumente kann in ein Wörterbuch verpackt, bzw. aus diesem ausgepackt werden.

Syntax bei der Funktionsdeklaration mit zwei Sternchen:

def f(**x):
    print(x)

# Argumente werden in das Wörterbuch x verpackt
f(tag='Montag', anzahl=5, preis=3.8)
def diskriminante(**x):
    '''berechnet die Diskriminante von a*x**2+b*x+c=0'''
    return x['b']**2-4*x['a']*x['c']

# Argumente werden in das Wörterbuch x verpackt
diskriminante(a=2, b=3.5, c=-4)

Syntax beim Aufruf:

def g(a=1, b=2):
    print(a*b)


wb = {'a': 5, 'b': 17}
g(**wb)  # Wörterbuch wird beim Aufruf ausgepackt

Kombination aller Arten von Argumenten

In Python-Lehrbüchern werden Positions-Argumente häufig mit pargs, die keyword-Argumente mit kwargs abgekürzt.

Man kann nun in einer Funktionsdeklaration einzelne Positionsargumente mit verpackten pargs und kwargs kombinieren:

def f(a, b, *pargs, **kwargs):
    print(("a: ", a))
    print(("b: ", b))
    print(("pargs: ", pargs))
    print(type(pargs))
    print(("kwargs: ", kwargs))
    print(type(kwargs))

f(11, 2, 3, 4, x=3.14, y=0.0)

Beachtedabei die Reihenfolge: Einzelne Positionsargumente – *pargs – **kwargs.

Beim Aufruf sieht das so aus:

def f(a, b, c, d, x=0.0, y=0.0):
    print(("a: ", a))
    print(("b: ", b))
    print(("c: ", c))
    print(("d: ", d))
    print(("x: ", x))
    print(("y: ", y))
    return a*b*c*d+x*y

liste = [2, 3]
woerterbuch = {'x': 10., 'y': 3.5}

f(1, 4, *liste, **woerterbuch)