Functions#

A function of good software is to make the complex appear simple.
— Grady Booch
Slides/PDF#
Function Definition and Function Call#
All higher-level programming languages allow the definition of functions (or procedures) to avoid having to write repetitive code and to structure complex programs.
Functions in Python are defined with the keyword def
. They have a function name
and can take multiple arguments as input in parentheses. The function declaration is terminated with :
. The body of the function, i.e., the part that should be executed when the function is called, must always be indented.
def function_name(argument1, argument2):
# Function body
print("Der Datentyp von Argument 1 ist "+str(type(argument1)))
print("Der Datentyp von Argument 2 ist "+str(type(argument2)))
All parts of the function must be indented to the same level. The following code is, for instance, syntactically incorrect.
def function_name(argument1, argument2):
# Function body
print("Der Datentyp von Argument 1 ist "+str(type(argument1)))
print("Der Datentyp von Argument 2 ist "+str(type(argument2)))
When calling the function with funktionsname(wert1, wert2)
, the arguments must be provided with input values. The arguments in Python are dynamically typed, like other variables (So we don’t necessarily know which data type they will have later. This is a common source of errors).
function_name("wert1", 2)
Der Datentyp von Argument 1 ist <class 'str'>
Der Datentyp von Argument 2 ist <class 'int'>
The crucial thing is that the arguments can change their values.
function_name("anderer wert ", "noch ein anderer")
Der Datentyp von Argument 1 ist <class 'str'>
Der Datentyp von Argument 2 ist <class 'str'>
Return of Results#
The return statement is used in functions to terminate the execution of a function and return the assigned value(s) as the function’s result.
def function_with_one_output():
return "Ausgabewert"
print("Dieser Teil wird nicht ausgeführt")
return "Anderer Ausgabewert"
result = function_with_one_output()
result
'Ausgabewert'
We can see that the result is Ausgabewert
and the print()
function has not been called.
Multiple return values can be returned using return
.
def function_with_two_outputs():
return "Ausgabewert1", "Ausgabewert2"
result = function_with_two_outputs()
result
('Ausgabewert1', 'Ausgabewert2')
The result of functions that return multiple values is a tuple.
type(result)
tuple
You can access the individual values in a tuple by their index. For reference, the index of a list or tuple starts at 0.
result[0]
'Ausgabewert1'
The tuple can, however, also be prevented by multiple assignment. In a multiple assignment, you list several variables separated by commas on the left-hand side of the assignment.
result1, result2 = function_with_two_outputs()
print(result1)
print(result2)
print(type(result1))
print(type(result2))
Ausgabewert1
Ausgabewert2
<class 'str'>
<class 'str'>
Variable Validity#
Variables inside functions are not globally valid. The variables for the arguments are valid only within the function. New variables defined inside the function are also not valid outside the function. This is how it works in the following function:
def my_function(argument):
internal_variable = "geheim"
print("Der Wert von argument innerhalb der Funktion ist "+str(argument))
print("Der Wert von internal_variable innerhalb der Funktion ist "+str(internal_variable))
The values of argument
and intern
are defined inside the function and are printed by the print()
statement.
my_function("argument_wert")
Der Wert von argument innerhalb der Funktion ist argument_wert
Der Wert von internal_variable innerhalb der Funktion ist geheim
However, the variables argument
and interne_variable
are not globally available after the function has been executed.
print(argument)
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
Cell In[14], line 1
----> 1 print(argument)
NameError: name 'argument' is not defined
print(internal_variable)
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
Cell In[15], line 1
----> 1 print(internal_variable)
NameError: name 'internal_variable' is not defined
It also allows defining variable names outside the function that can have a different value inside the function. This keeps the value of argument
unchanged.
argument = 6 # original value
print("Der Wert von argument vor der Funktion ist "+str(argument))
my_function(4)
print("Der Wert von argument nach der Funktion ist immer noch "+str(argument))
Der Wert von argument vor der Funktion ist 6
Der Wert von argument innerhalb der Funktion ist 4
Der Wert von internal_variable innerhalb der Funktion ist geheim
Der Wert von argument nach der Funktion ist immer noch 6
Modified and Unmodified Arguments#
As a rule, modifications to primitive-type arguments inside a function are not carried over (pass-by-value). Thus, inside the function you can also assign new values to the arguments.
def my_function(argument):
print("Der Wert von argument am Anfang der Funktion ist "+str(argument))
argument = 3
print("Der Wert von argument am Ende der Funktion ist "+str(argument))
argument = 6 # original value
print("Der Wert von argument vor der Funktion ist "+str(argument))
my_function(argument)
print("Der Wert von argument nach der Funktion ist immer noch "+str(argument))
Der Wert von argument vor der Funktion ist 6
Der Wert von argument am Anfang der Funktion ist 6
Der Wert von argument am Ende der Funktion ist 3
Der Wert von argument nach der Funktion ist immer noch 6
This also works with complex data types, such as list
, set
, and dict
, as long as they are completely reassigned.
def my_function(argument):
print("Der Wert von argument am Anfang der Funktion ist "+str(argument))
argument = [3]
print("Der Wert von argument am Ende der Funktion ist "+str(argument))
argument = [6] # original value
print("Der Wert von argument vor der Funktion ist "+str(argument))
my_function(argument)
print("Der Wert von argument nach der Funktion ist immer noch "+str(argument))
Der Wert von argument vor der Funktion ist [6]
Der Wert von argument am Anfang der Funktion ist [6]
Der Wert von argument am Ende der Funktion ist [3]
Der Wert von argument nach der Funktion ist immer noch [6]
However, if they are modified only by pass-by-reference, these changes are global as well.
def my_function(argument):
print("Der Wert von argument am Anfang der Funktion ist "+str(argument))
argument.append(3) # We append 3 to the list
print("Der Wert von argument am Ende der Funktion ist "+str(argument))
argument = [6] # original value
print("Der Wert von argument vor der Funktion ist "+str(argument))
my_function(argument)
print("Der Wert von argument nach der Funktion ist auf einmal "+str(argument))
Der Wert von argument vor der Funktion ist [6]
Der Wert von argument am Anfang der Funktion ist [6]
Der Wert von argument am Ende der Funktion ist [6, 3]
Der Wert von argument nach der Funktion ist auf einmal [6, 3]