Python & AI Tutorials Logo
Python Programmierung

19. Funktionen definieren und aufrufen

19.1) Was Funktionen sind und warum sie wichtig sind

Eine Funktion(function) ist ein benannter Codeblock, der eine bestimmte Aufgabe ausführt. Sie haben in diesem Buch bereits durchgehend Funktionen verwendet—print(), input(), len(), type() und viele andere. Das sind eingebaute Funktionen (built-in functions), die Python bereitstellt. Jetzt lernen Sie, Ihre eigenen benutzerdefinierten Funktionen (custom functions) zu erstellen, um Ihren Code zu organisieren und wiederverwendbar zu machen.

Warum Funktionen wichtig sind

Funktionen sind grundlegend, um klare, wartbare Programme zu schreiben. Sie bieten mehrere entscheidende Vorteile:

1. Wiederverwendbarkeit von Code

Ohne Funktionen müssten Sie denselben Code jedes Mal kopieren und einfügen, wenn Sie eine Aufgabe ausführen möchten. Denken Sie an die Flächenberechnung eines Rechtecks an mehreren Stellen:

python
# Ohne Funktionen – repetitiver Code
length1 = 5
width1 = 3
area1 = length1 * width1
print(f"Area 1: {area1}")
 
length2 = 8
width2 = 4
area2 = length2 * width2
print(f"Area 2: {area2}")
 
length3 = 10
width3 = 6
area3 = length3 * width3
print(f"Area 3: {area3}")

Output:

Area 1: 15
Area 2: 32
Area 3: 60

Diese Wiederholung ist mühsam und fehleranfällig. Wenn Sie ändern müssen, wie Sie die Fläche berechnen (vielleicht um Einheiten oder Rundung einzubeziehen), müssten Sie jede Stelle aktualisieren. Funktionen lösen dieses Problem, indem Sie den Code einmal schreiben und ihn viele Male verwenden können.

2. Code-Organisation

Funktionen zerlegen große Programme in kleinere, handhabbare Teile. Jede Funktion übernimmt eine bestimmte Aufgabe, wodurch Ihr Code leichter zu verstehen und zu warten ist. Statt eines langen Skripts mit Hunderten Zeilen können Sie zusammengehörige Operationen in benannte Funktionen organisieren, die ihren Zweck klar kommunizieren.

3. Abstraktion (abstraction)

Funktionen verbergen Implementierungsdetails hinter einer einfachen Schnittstelle. Wenn Sie len(my_list) aufrufen, müssen Sie nicht wissen, wie Python die Elemente zählt—Sie erhalten einfach das Ergebnis. Ebenso können Ihre Funktionen einfache Schnittstellen für komplexe Operationen bereitstellen, wodurch Ihr Code leichter zu verwenden und zu verstehen ist.

4. Testen und Debugging

Funktionen erleichtern es, einzelne Teile Ihres Programms zu testen. Sie können überprüfen, dass jede Funktion isoliert korrekt funktioniert, bevor Sie sie zu einem größeren Programm zusammensetzen. Wenn etwas schiefgeht, helfen Funktionen Ihnen, einzugrenzen, wo das Problem auftritt.

Im restlichen Verlauf dieses Kapitels lernen Sie, wie Sie Ihre eigenen Funktionen definieren, Informationen an sie übergeben, Ergebnisse zurückbekommen und sie klar dokumentieren. Diese Fähigkeiten sind essenziell, um professionellen Python-Code zu schreiben.

19.2) Funktionen mit def definieren

Um eine Funktion(function) in Python zu erstellen, verwenden Sie das Schlüsselwort def (kurz für „define“). Die Grundstruktur einer Funktionsdefinition sieht so aus:

python
def function_name():
    # Codeblock, der ausgeführt wird, wenn die Funktion aufgerufen wird
    statement1
    statement2
    # ... weitere Anweisungen

Sehen wir uns jeden Teil an:

  • def: Das Schlüsselwort, das Python mitteilt, dass Sie eine Funktion definieren
  • function_name: Der Name, den Sie für Ihre Funktion wählen (folgt denselben Regeln wie Variablennamen)
  • (): Klammern, die später Parameter enthalten (die behandeln wir im nächsten Abschnitt)
  • :: Ein Doppelpunkt, der das Ende des Funktionskopfs markiert
  • Eingerückter Codeblock: Die Anweisungen, aus denen der Funktionskörper besteht (muss eingerückt sein)

Ihre erste Funktion

Hier ist eine einfache Funktion, die eine Begrüßung ausgibt:

python
def greet():
    print("Hello!")
    print("Welcome to Python functions.")
 
# Call the function
greet()

Output:

Hello!
Welcome to Python functions.

Wenn Sie eine Funktion definieren, merkt Python sie sich, führt den Code darin aber nicht sofort aus. Der Code läuft erst, wenn Sie die Funktion aufrufen (call), indem Sie ihren Namen gefolgt von Klammern schreiben: greet().

Namenskonventionen für Funktionen

Funktionsnamen folgen denselben Regeln wie Variablennamen (wie wir in Kapitel 3 gelernt haben):

  • Verwenden Sie Kleinbuchstaben
  • Trennen Sie Wörter mit Unterstrichen (snake_case)
  • Beginnen Sie mit einem Buchstaben oder Unterstrich, nicht mit einer Ziffer
  • Verwenden Sie aussagekräftige Namen, die anzeigen, was die Funktion tut
python
# Gute Funktionsnamen
def calculate_total():
    pass
 
def get_user_age():
    pass
 
def display_menu():
    pass
 
# Schlechte Funktionsnamen (aber syntaktisch gültig)
def x():  # Nicht aussagekräftig
    pass
 
def CalculateTotal():  # Sollte Kleinbuchstaben verwenden
    pass
 
def calc():  # Zu stark abgekürzt
    pass

Hinweis: Wir verwenden pass hier als Platzhalter (wie wir in Kapitel 8 gelernt haben). Es tut nichts, erlaubt aber, dass die Funktionsdefinition syntaktisch vollständig ist.

Funktionen können jeden Code enthalten

Der Körper einer Funktion kann beliebige Python-Anweisungen enthalten, die Sie bisher gelernt haben: Variablenzuweisungen, Bedingungen, Schleifen(loop) und sogar Aufrufe anderer Funktionen.

python
def check_temperature():
    temperature = 72
    if temperature > 75:
        print("It's warm.")
    elif temperature > 60:
        print("It's comfortable.")
    else:
        print("It's cool.")
 
check_temperature()

Output:

It's comfortable.

Mehrere Funktionsdefinitionen

Sie können so viele Funktionen definieren, wie Sie in Ihrem Programm benötigen. Jede Funktion ist unabhängig und kann separat aufgerufen werden:

python
def morning_greeting():
    print("Good morning!")
 
def evening_greeting():
    print("Good evening!")
 
# Call each function
morning_greeting()
evening_greeting()

Output:

Good morning!
Good evening!

Reihenfolge der Funktionsdefinition

In Python müssen Sie eine Funktion definieren, bevor Sie sie aufrufen. Der Python-Interpreter liest Ihren Code von oben nach unten. Wenn Sie also versuchen, eine Funktion aufzurufen, bevor sie definiert ist, erhalten Sie einen Fehler:

python
# WARNING: This will cause a NameError - for demonstration only
# PROBLEM: Function called before it's defined
say_hello()  # NameError: name 'say_hello' is not defined
 
def say_hello():
    print("Hello!")

Die korrekte Reihenfolge ist: zuerst definieren, dann aufrufen:

python
# Korrekt: Zuerst definieren
def say_hello():
    print("Hello!")
 
# Dann aufrufen
say_hello()

Output:

Hello!

Allerdings können Funktionen andere Funktionen aufrufen, die später in der Datei definiert sind, solange diese Aufrufe erst stattfinden, nachdem alle Definitionen vorhanden sind:

python
def first_function():
    print("First function")
    second_function()  # Das ist in Ordnung – wird zur Laufzeit aufgerufen
 
def second_function():
    print("Second function")
 
# Beide Funktionen sind definiert, bevor wir die erste aufrufen
first_function()

Output:

First function
Second function

Funktionen erzeugen einen lokalen Gültigkeitsbereich

Variablen, die innerhalb einer Funktion erstellt werden, existieren nur innerhalb dieser Funktion. Das nennt man lokalen Gültigkeitsbereich (local scope) (wir werden das in Kapitel 21 im Detail betrachten). Verstehen Sie fürs Erste, dass das, was innerhalb einer Funktion passiert, innerhalb der Funktion bleibt:

python
def create_message():
    message = "This is local"
    print(message)
 
create_message()
 
# This would cause an error:
# print(message)  # NameError: name 'message' is not defined

Output:

This is local

Die Variable message existiert nur, während die Funktion läuft. Sobald die Funktion endet, verschwindet die Variable.

Leere Funktionen mit pass

Manchmal möchten Sie eine Funktionsstruktur definieren, sie aber erst später implementieren. Verwenden Sie pass als Platzhalter:

python
def future_feature():
    pass  # TODO: Implement this later
 
# Die Funktion existiert und kann aufgerufen werden, tut aber nichts
future_feature()  # Läuft ohne Fehler, tut nichts

Das ist nützlich, wenn Sie zuerst die Struktur Ihres Programms skizzieren, bevor Sie die Details ausarbeiten.

19.3) Funktionen aufrufen und Argumente übergeben

Das Definieren einer Funktion erstellt ein wiederverwendbares Code-Stück, aber um Funktionen wirklich leistungsfähig zu machen, müssen Sie Informationen an sie übergeben. Diese Informationen werden über Argumente (arguments) übergeben.

Parameter vs. Argumente

Bevor wir weitermachen, klären wir zwei Begriffe, die oft verwechselt werden:

  • Parameter (parameter): Ein Variablenname in der Funktionsdefinition, der einen Wert entgegennimmt
  • Argument (argument): Der tatsächliche Wert, den Sie der Funktion beim Aufruf übergeben
python
def greet(name):  # 'name' ist ein Parameter
    print(f"Hello, {name}!")
 
greet("Alice")  # "Alice" ist ein Argument

Output:

Hello, Alice!

Denken Sie an Parameter als Platzhalter und an Argumente als die tatsächlichen Daten, die diese Platzhalter füllen.

Funktionen mit Parametern definieren

Um eine Funktion zu definieren, die Eingaben akzeptiert, fügen Sie Parameternamen innerhalb der Klammern hinzu:

python
def greet_person(name):
    print(f"Hello, {name}!")
    print("Nice to meet you.")
 
# Mit unterschiedlichen Argumenten aufrufen
greet_person("Alice")
print()  # Leere Zeile für bessere Lesbarkeit
greet_person("Bob")

Output:

Hello, Alice!
Nice to meet you.
 
Hello, Bob!
Nice to meet you.

Der Parameter name fungiert innerhalb der Funktion als Variable. Jedes Mal, wenn Sie die Funktion aufrufen, nimmt name den Wert des Arguments an, das Sie angeben.

Mehrere Parameter

Funktionen können mehrere Parameter akzeptieren, durch Kommas getrennt:

python
def calculate_rectangle_area(length, width):
    area = length * width
    print(f"A rectangle with length {length} and width {width}")
    print(f"has an area of {area} square units.")
 
calculate_rectangle_area(5, 3)
print()
calculate_rectangle_area(10, 7)

Output:

A rectangle with length 5 and width 3
has an area of 15 square units.
 
A rectangle with length 10 and width 7
has an area of 70 square units.

Beim Aufruf einer Funktion mit mehreren Parametern ist die Reihenfolge wichtig. Das erste Argument geht an den ersten Parameter, das zweite Argument an den zweiten Parameter und so weiter. Diese nennt man Positionsargumente (positional arguments).

Positionsargumente

Bei Positionsargumenten ordnet Python Argumente den Parametern anhand ihrer Position zu:

python
def describe_pet(animal_type, pet_name):
    print(f"I have a {animal_type}.")
    print(f"My {animal_type}'s name is {pet_name}.")
 
describe_pet("dog", "Buddy")
print()
describe_pet("cat", "Whiskers")

Output:

I have a dog.
My dog's name is Buddy.
 
I have a cat.
My cat's name is Whiskers.

Wenn Sie die Reihenfolge vertauschen, erhalten Sie unerwartete Ergebnisse:

python
def describe_pet(animal_type, pet_name):
    print(f"I have a {animal_type}.")
    print(f"My {animal_type}'s name is {pet_name}.")
 
# Arguments in wrong order
describe_pet("Buddy", "dog")

Output:

I have a Buddy.
My Buddy's name is dog.

Das ist technisch gültiges Python, aber es erzeugt unsinnige Ausgabe, weil die Argumente an den falschen Positionen stehen.

Schlüsselwortargumente

Um positionsbedingte Fehler zu vermeiden, können Sie Schlüsselwortargumente (keyword arguments) verwenden, indem Sie die Parameter beim Aufruf explizit benennen:

python
def describe_pet(animal_type, pet_name):
    print(f"I have a {animal_type}.")
    print(f"My {animal_type}'s name is {pet_name}.")
 
# Using keyword arguments - order doesn't matter
describe_pet(animal_type="dog", pet_name="Buddy")
print()
describe_pet(pet_name="Whiskers", animal_type="cat")

Output:

I have a dog.
My dog's name is Buddy.
 
I have a cat.
My cat's name is Whiskers.

Mit Schlüsselwortargumenten ist die Reihenfolge egal, weil Python Argumente den Parametern anhand des Namens zuordnet, nicht anhand der Position.

Positions- und Schlüsselwortargumente mischen

Sie können Positions- und Schlüsselwortargumente in einem einzelnen Funktionsaufruf mischen, aber Positionsargumente müssen zuerst kommen:

python
def create_profile(username, email, age):
    print(f"Username: {username}")
    print(f"Email: {email}")
    print(f"Age: {age}")
 
# Mixing positional and keyword arguments
create_profile("alice123", email="alice@example.com", age=25)

Output:

Username: alice123
Email: alice@example.com
Age: 25

Allerdings können Sie keine Positionsargumente nach Schlüsselwortargumenten setzen:

python
# WARNING: This will cause a SyntaxError - for demonstration only
# PROBLEM: Positional argument after keyword argument
# create_profile(username="alice123", "alice@example.com", 25)
# SyntaxError: positional argument follows keyword argument

Die Anzahl der Argumente muss passen

Wenn Sie eine Funktion aufrufen, müssen Sie die korrekte Anzahl an Argumenten angeben (außer die Funktion hat Standardwerte, die wir in Kapitel 20 behandeln):

python
def add_numbers(a, b):
    result = a + b
    print(f"{a} + {b} = {result}")
 
add_numbers(5, 3)  # Korrekt: 2 Argumente für 2 Parameter

Output:

5 + 3 = 8

Zu wenige oder zu viele Argumente führen zu einem Fehler:

python
# WARNING: These will cause TypeErrors - for demonstration only
 
# PROBLEM: Too few arguments
# add_numbers(5)
# TypeError: add_numbers() missing 1 required positional argument: 'b'
 
# PROBLEM: Too many arguments
# add_numbers(5, 3, 2)
# TypeError: add_numbers() takes 2 positional arguments but 3 were given

Ausdrücke als Argumente verwenden

Argumente müssen keine einfachen Werte sein—Sie können jeden Ausdruck verwenden:

python
def display_total(price, quantity):
    total = price * quantity
    print(f"Total cost: ${total:.2f}")
 
# Ausdrücke als Argumente verwenden
base_price = 10
display_total(base_price * 1.1, 5)  # Preis mit 10 % Aufschlag
display_total(15 + 5, 3 * 2)        # Beide Argumente sind Ausdrücke

Output:

Total cost: $55.00
Total cost: $120.00

Python wertet jeden Ausdruck zuerst aus und übergibt dann die resultierenden Werte an die Funktion.

Funktionen innerhalb von Funktionen aufrufen

Funktionen können andere Funktionen aufrufen und so eine Hierarchie von Operationen bilden. Das ist eine leistungsstarke Technik, mit der Sie komplexe Aufgaben in kleinere, handhabbare Teile zerlegen können.

Hier ist ein Beispiel mit der Flächenberechnung eines Raums:

python
def calculate_area(length, width):
    return length * width
 
def display_room_info(room_name, length, width):
    area = calculate_area(length, width)
    print(f"Room: {room_name}")
    print(f"Dimensions: {length} x {width}")
    print(f"Area: {area} square feet")
 
display_room_info("Living Room", 15, 12)

Output:

Room: Living Room
Dimensions: 15 x 12
Area: 180 square feet

Hinweis: Wir verwenden hier return, das wir im nächsten Abschnitt im Detail betrachten. Verstehen Sie fürs Erste, dass calculate_area() sein Ergebnis an die aufrufende Funktion zurückgibt.

Hier ist ein weiteres Beispiel, das zeigt, wie Funktionen aufeinander aufbauen können—ein Temperatur-Umrechnungssystem:

python
def celsius_to_fahrenheit(celsius):
    return (celsius * 9/5) + 32
 
def format_temperature(fahrenheit):
    return f"{fahrenheit:.1f}°F"
 
def display_temperature_conversion(celsius):
    fahrenheit = celsius_to_fahrenheit(celsius)
    formatted = format_temperature(fahrenheit)
    print(f"{celsius}°C equals {formatted}")
 
# Use the complete conversion system
display_temperature_conversion(25)
display_temperature_conversion(0)
display_temperature_conversion(100)

Output:

25°C equals 77.0°F
0°C equals 32.0°F
100°C equals 212.0°F

In diesem Beispiel ruft display_temperature_conversion() celsius_to_fahrenheit() auf, um die Umrechnung durchzuführen, und ruft dann format_temperature() auf, um das Ergebnis zu formatieren. Jede Funktion hat eine einzelne, klare Verantwortung, wodurch der Code leicht zu verstehen und zu warten ist.

19.4) return verwenden, um Ergebnisse zurückzugeben

Bisher haben unsere Funktionen Aktionen ausgeführt (wie Ausgaben), aber sie haben keine Werte an den Code zurückgegeben, der sie aufgerufen hat. Die return-Anweisung ermöglicht es einer Funktion, ein Ergebnis zu berechnen und es an den Aufrufer zurückzusenden.

Grundlegende return-Anweisung

Hier ist eine einfache Funktion, die einen Wert berechnet und zurückgibt:

python
def add_numbers(a, b):
    result = a + b
    return result
 
# Capture the returned value
sum_value = add_numbers(5, 3)
print(f"The sum is: {sum_value}")

Output:

The sum is: 8

Wenn Python auf eine return-Anweisung trifft, passieren zwei Dinge:

  1. Die Funktion beendet die Ausführung sofort (jeder Code nach return wird ignoriert)
  2. Der angegebene Wert wird an den Aufrufer zurückgesendet

Werte direkt zurückgeben

Sie müssen das Ergebnis nicht in einer Variablen speichern, bevor Sie es zurückgeben. Sie können einen Ausdruck direkt zurückgeben:

python
def multiply(a, b):
    return a * b
 
result = multiply(4, 7)
print(f"4 × 7 = {result}")

Output:

4 × 7 = 28

Das ist knapper und ist der bevorzugte Stil für einfache Berechnungen.

Zurückgegebene Werte verwenden

Sobald eine Funktion einen Wert zurückgibt, können Sie diesen Wert überall dort verwenden, wo Sie sonst auch irgendeinen Wert verwenden würden:

python
def calculate_discount(price, discount_percent):
    discount_amount = price * (discount_percent / 100)
    return discount_amount
 
original_price = 100
discount = calculate_discount(original_price, 20)
 
# Den zurückgegebenen Wert in Berechnungen verwenden
final_price = original_price - discount
print(f"Original price: ${original_price:.2f}")
print(f"Discount: ${discount:.2f}")
print(f"Final price: ${final_price:.2f}")

Output:

Original price: $100.00
Discount: $20.00
Final price: $80.00

return beendet die Funktion sofort

Wenn Python eine return-Anweisung ausführt, endet die Funktion sofort. Jeder Code nach return wird nie ausgeführt:

python
def check_age(age):
    if age < 18:
        return "Minor"
    # Diese Zeile läuft nur, wenn age >= 18
    return "Adult"
 
print(check_age(15))
print(check_age(25))

Output:

Minor
Adult

Dieses Verhalten ist nützlich, um unterschiedliche Fälle in einer Funktion zu behandeln. Sobald Sie das Ergebnis bestimmt haben, können Sie sofort zurückgeben, ohne zusätzliche Bedingungen prüfen zu müssen.

Hier ist ein Beispiel, das demonstriert, wie return die Ausführung stoppt:

python
def process_number(n):
    if n < 0:
        return "Negative"
    print("This line runs for non-negative numbers")
    if n == 0:
        return "Zero"
    print("This line runs for positive numbers")
    return "Positive"
 
print(process_number(-5))
print()
print(process_number(0))
print()
print(process_number(10))

Output:

Negative
 
This line runs for non-negative numbers
Zero
 
This line runs for non-negative numbers
This line runs for positive numbers
Positive

Funktionen ohne return

Wenn eine Funktion keine return-Anweisung hat oder wenn sie ein return ohne Wert hat, gibt die Funktion None zurück:

python
def greet(name):
    print(f"Hello, {name}!")
    # Keine return-Anweisung
 
result = greet("Alice")
print(f"The function returned: {result}")

Output:

Hello, Alice!
The function returned: None

Ebenso gibt ein nacktes return (ohne Wert) auch None zurück:

python
def process_data(data):
    if not data:
        return  # Früher Ausstieg, gibt None zurück
    print(f"Processing: {data}")
    return "Success"
 
result1 = process_data("")
result2 = process_data("some data")
 
print(f"Result 1: {result1}")
print(f"Result 2: {result2}")

Output:

Processing: some data
Result 1: None
Result 2: Success

Mehrere Werte zurückgeben

Python-Funktionen können mehrere Werte zurückgeben, indem Sie sie mit Kommas trennen. Python packt sie automatisch in ein Tupel(tuple) (wie wir in Kapitel 15 gelernt haben):

python
def calculate_rectangle(length, width):
    area = length * width
    perimeter = 2 * (length + width)
    return area, perimeter
 
# Unpack the returned tuple
rect_area, rect_perimeter = calculate_rectangle(5, 3)
print(f"Area: {rect_area}")
print(f"Perimeter: {rect_perimeter}")

Output:

Area: 15
Perimeter: 16

Sie können das Tupel auch als einzelnen Wert erfassen:

python
def get_student_info():
    name = "Alice"
    age = 20
    grade = "A"
    return name, age, grade
 
# Capture as a tuple
student = get_student_info()
print(f"Student info: {student}")
print(f"Name: {student[0]}")

Output:

Student info: ('Alice', 20, 'A')
Name: Alice

Unterschiedliche Typen zurückgeben

Eine Funktion kann je nach Situation unterschiedliche Typen von Werten zurückgeben:

python
def divide(a, b):
    if b == 0:
        return "Error: Division by zero"
    return a / b
 
result1 = divide(10, 2)
result2 = divide(10, 0)
 
print(f"10 / 2 = {result1}")
print(f"10 / 0 = {result2}")

Output:

10 / 2 = 5.0
10 / 0 = Error: Division by zero

Auch wenn das funktioniert, ist es in der Regel bessere Praxis, Fehler anders zu behandeln (wir lernen in Teil VII etwas über Exceptions). Verstehen Sie fürs Erste, dass Funktionen unterschiedliche Typen zurückgeben können, auch wenn es oft klarer ist, konsistent zu bleiben.

19.5) Funktionen mit Docstrings dokumentieren

Wenn Ihre Programme wachsen und Sie mehr Funktionen erstellen, wird es entscheidend, zu dokumentieren, was jede Funktion tut. Python bietet eine eingebaute Möglichkeit, Funktionen mit Docstrings(docstrings) (Dokumentationsstrings) zu dokumentieren.

Was ist ein Docstring?

Ein Docstring(docstring) ist ein String-Literal, das als erste Anweisung in einer Funktion (oder einem Modul, einer Klasse oder einer Methode) erscheint. Er beschreibt, was die Funktion tut, welche Parameter sie akzeptiert und was sie zurückgibt. Docstrings werden in dreifache Anführungszeichen (""" oder ''') gesetzt, wodurch sie mehrere Zeilen umfassen können.

python
def calculate_area(length, width):
    """Calculate the area of a rectangle.
    
    Takes the length and width of a rectangle and returns the area.
    """
    return length * width

Warum Docstrings wichtig sind

Docstrings erfüllen mehrere wichtige Zwecke:

  1. Selbstdokumentation: Sie erklären, was Ihre Funktion tut, ohne dass Leser den Code analysieren müssen
  2. IDE-Unterstützung: Viele Entwicklungstools zeigen Docstrings als Tooltips an, wenn Sie eine Funktion verwenden
  3. help()-Funktion: Pythons eingebaute help()-Funktion zeigt Docstrings an
  4. Professionelle Praxis: Gut dokumentierter Code ist leichter zu warten und mit anderen zu teilen

Grundlegendes Docstring-Format

Für einfache Funktionen reicht ein einzeiliger Docstring aus:

python
def greet(name):
    """Print a personalized greeting."""
    print(f"Hello, {name}!")
 
# Auf den Docstring zugreifen
print(greet.__doc__)

Output:

Print a personalized greeting.

Der Docstring sollte eine knappe Beschreibung dessen sein, was die Funktion tut, formuliert als Aufforderung („Calculate...“, „Return...“, „Print...“) statt als Beschreibung („This function calculates...“).

Mehrzeilige Docstrings

Für komplexere Funktionen verwenden Sie mehrzeilige Docstrings, die Folgendes enthalten:

  • Eine kurze Zusammenfassung in der ersten Zeile
  • Eine Leerzeile
  • Eine detailliertere Beschreibung
  • Informationen über Parameter
  • Informationen über Rückgabewerte
python
def calculate_discount(price, discount_percent):
    """Calculate the discounted price.
    
    Takes an original price and a discount percentage, then returns
    the amount of discount that should be applied.
    
    Parameters:
    price (float): The original price before discount
    discount_percent (float): The discount percentage (0-100)
    
    Returns:
    float: The discount amount in the same currency as the price
    """
    return price * (discount_percent / 100)
 
# Use help() to see the full docstring
help(calculate_discount)

Output:

Help on function calculate_discount in module __main__:
 
calculate_discount(price, discount_percent)
    Calculate the discounted price.
    
    Takes an original price and a discount percentage, then returns
    the amount of discount that should be applied.
    
    Parameters:
    price (float): The original price before discount
    discount_percent (float): The discount percentage (0-100)
    
    Returns:
    float: The discount amount in the same currency as the price

Docstring-Konventionen

Python hat etablierte Konventionen für das Schreiben von Docstrings (dokumentiert in PEP 257). Hier sind die wichtigsten Richtlinien:

1. Verwenden Sie dreifache doppelte Anführungszeichen: """docstring"""

python
def good_example():
    """This follows the convention."""
    pass
 
def also_valid():
    '''This works but is less common.'''
    pass

2. Einzeilige Docstrings sollten in eine Zeile passen:

python
def add(a, b):
    """Return the sum of a and b."""
    return a + b

3. Mehrzeilige Docstrings sollten eine Zusammenfassungszeile haben, dann eine Leerzeile:

python
def process_order(order_id, items):
    """Process a customer order and update inventory.
    
    This function validates the order, checks inventory availability,
    calculates the total cost, and updates the inventory database.
    
    Parameters:
    order_id (str): Unique identifier for the order
    items (list): List of item dictionaries with 'product' and 'quantity'
    
    Returns:
    dict: Order summary with 'total', 'status', and 'confirmation_number'
    """
    # Funktionsimplementierung hier
    pass

Parameter und Rückgabewerte beschreiben

Wenn Sie Parameter und Rückgabewerte dokumentieren, seien Sie spezifisch bezüglich:

  • Parameternamen: Stimmen Sie die tatsächlichen Parameternamen in der Funktion ab
  • Typen: Welcher Datentyp erwartet wird (wir lernen in Kapitel 43 etwas über Type Hints)
  • Zweck: Wofür der Parameter verwendet wird
  • Rückgabewert: Was die Funktion zurückgibt und unter welchen Bedingungen
python
def find_student(student_id, students):
    """Find a student by ID in a list of student records.
    
    Parameters:
    student_id (int): The unique ID number of the student to find
    students (list): List of student dictionaries, each containing 'id' and 'name'
    
    Returns:
    dict: The student dictionary if found, None if not found
    """
    for student in students:
        if student['id'] == student_id:
            return student
    return None

Docstrings für Funktionen mit mehreren Rückgabetypen

Wenn eine Funktion je nach Situation unterschiedliche Typen zurückgeben kann, dokumentieren Sie alle Möglichkeiten:

python
def safe_divide(a, b):
    """Divide two numbers with error handling.
    
    Parameters:
    a (float): The dividend
    b (float): The divisor
    
    Returns:
    float: The quotient if division is successful
    str: An error message if b is zero
    """
    if b == 0:
        return "Error: Cannot divide by zero"
    return a / b

Auf Docstrings zugreifen

Sie können auf den Docstring einer Funktion auf drei Arten zugreifen:

1. Über das Attribut __doc__:

python
def example():
    """This is an example function."""
    pass
 
print(example.__doc__)

Output:

This is an example function.

2. Über die help()-Funktion:

python
def calculate_bmi(weight, height):
    """Calculate Body Mass Index.
    
    Parameters:
    weight (float): Weight in kilograms
    height (float): Height in meters
    
    Returns:
    float: BMI value
    """
    return weight / (height ** 2)
 
help(calculate_bmi)

Output:

Help on function calculate_bmi in module __main__:
 
calculate_bmi(weight, height)
    Calculate Body Mass Index.
    
    Parameters:
    weight (float): Weight in kilograms
    height (float): Height in meters
    
    Returns:
    float: BMI value

3. In interaktiven Entwicklungsumgebungen: Die meisten IDEs und Code-Editoren zeigen Docstrings als Tooltips an, wenn Sie über einen Funktionsnamen fahren oder ihn tippen.

Wann man Docstrings schreiben sollte

Sie sollten Docstrings schreiben für:

  • Alle öffentlichen Funktionen: Funktionen, die von anderen Teilen Ihres Programms oder von anderen Programmierern verwendet werden sollen
  • Komplexe Funktionen: Jede Funktion, deren Zweck oder Verhalten nicht sofort aus Name und Parametern ersichtlich ist
  • Funktionen mit nicht offensichtlichen Parametern: Wenn Parameternamen allein nicht vollständig erklären, welche Werte erwartet werden

Sie können Docstrings weglassen für:

  • Sehr einfache, offensichtliche Funktionen: Funktionen wie def add(a, b): return a + b, bei denen Name und Parameter den Zweck glasklar machen
  • Private Hilfsfunktionen: Kleine interne Funktionen, die nur innerhalb einer größeren Funktion verwendet werden (auch wenn selbst diese von kurzen Docstrings profitieren)

Docstrings sind keine Kommentare

Denken Sie daran, dass Docstrings einen anderen Zweck erfüllen als Kommentare:

  • Docstrings: Beschreiben, was eine Funktion tut und wie man sie verwendet (die Schnittstelle)
  • Kommentare: Erklären, wie der Code intern funktioniert (die Implementierung)
python
def calculate_grade(score, total):
    """Calculate the percentage grade from a score.
    
    Parameters:
    score (int): Points earned
    total (int): Total points possible
    
    Returns:
    float: The percentage grade (0-100)
    """
    # Division durch Null vermeiden
    if total == 0:
        return 0.0
    
    # Prozentwert berechnen und auf 2 Nachkommastellen runden
    percentage = (score / total) * 100
    return round(percentage, 2)

Der Docstring sagt Nutzern, was die Funktion tut und wie man sie verwendet. Die Kommentare erklären spezifische Implementierungsdetails für jemanden, der den Code liest.

Gute Dokumentationsgewohnheiten aufbauen

Klare Docstrings zu schreiben ist eine Gewohnheit, die sich auszahlt:

  • Schreiben Sie Docstrings, während Sie Funktionen schreiben: Warten Sie nicht bis später—dokumentieren Sie, solange der Zweck der Funktion noch frisch ist
  • Halten Sie Docstrings aktuell: Wenn Sie das Verhalten einer Funktion ändern, aktualisieren Sie ihren Docstring
  • Seien Sie knapp, aber vollständig: Nehmen Sie alle notwendigen Informationen auf, aber vermeiden Sie unnötige Ausführlichkeit
  • Verwenden Sie Beispiele, wenn hilfreich: Für komplexe Funktionen kann ein Verwendungsbeispiel im Docstring unschätzbar sein

Gute Dokumentation macht Ihren Code professioneller, leichter zu warten und wertvoller für andere (einschließlich Ihres zukünftigen Ichs).

© 2025. Primesoft Co., Ltd.
support@primesoft.ai