Python-Funktionen

Lerne, eigene Funktionen in Python zu schreiben. Definiere und rufe Funktionen auf, übergib Werte mit Parametern, Schlüsselwortargumenten und Standardwerten und gib Ergebnisse mit return zurück. Finde heraus, auf welche Variablen eine Funktion zugreifen kann und welche sie ändern kann, beschreibe deine Funktionen mit Docstrings und zerlege ein Programm in kleine, gut benannte Funktionen, die du einzeln erstellst und prüfst.

AnfängerEinheit 4 von 10 in Kurs: Python-Programmierung – Schleifen, Funktionen, Listen und Dateien

Was du lernst

  1. Schreibe eine Funktion mit def, führe sie durch einen Aufruf aus und verfolge, in welcher Reihenfolge Python ein Programm mit Funktionen ausführt.
    • Eine Funktion definieren und aufrufen
      Schreibe einen Funktionskopf und einen eingerückten Funktionskörper, wähle einen eindeutigen Namen und führe die Funktion durch einen Aufruf mit runden Klammern aus.
    • Den Programmablauf nachvollziehen
      Verfolge die Reihenfolge, in der Python Anweisungen ausführt, wenn Funktionen andere Funktionen aufrufen, und sage daraus die Ausgabe eines Programms voraus.
  2. Gib einer Funktion mit Parametern und Argumenten die Werte, die sie verarbeitet. Die Zuordnung erfolgt nach Position, nach Namen oder über Standardwerte.
    • Parameter und Positionsargumente verwenden
      Ergänze Parameter im Funktionskopf, übergib passende Argumente bei einem Aufruf und lies die Fehler, die durch eine falsche Anzahl von Argumenten entstehen.
    • Funktionen mit Schlüsselwortargumenten aufrufen
      Übergib Argumente anhand des Parameternamens, kombiniere Positions- und Schlüsselwortargumente in der richtigen Reihenfolge und behebe Fehler durch falsche Kombinationen.
    • Parametern Standardwerte geben
      Mache Parameter mithilfe von Standardwerten optional, ordne erforderliche und optionale Parameter richtig an und lerne, wann ein Standardwert erstellt wird.
  3. Übergib mit return einen Wert an den Code zurück, der eine Funktion aufgerufen hat, unterscheide Rückgabe und Ausgabe und schreibe Funktionen, deren Ergebnisse gespeichert, geprüft und kombiniert werden können.
    • Einen Wert zurückgeben und verwenden
      Beende eine Funktion mit return, verwende den zurückgegebenen Wert in Variablen und Ausdrücken und erkenne, warum sich die Rückgabe eines Werts von seiner Ausgabe unterscheidet.
    • Über verschiedene Pfade Werte zurückgeben und Ergebnisse kombinieren
      Schreibe Funktionen mit mehreren return-Anweisungen, gib True oder False zurück, kehre vorzeitig aus einer Schleife zurück, gib zwei Werte zurück und übergib das Ergebnis einer Funktion an eine andere.
  4. Sage voraus, auf welche Variablen eine Funktion zugreifen kann und welche sie ändern kann, übergib Daten über Parameter und Rückgabewerte und verwende global nur, wenn es wirklich nötig ist.
    • Mit lokalen Variablen und Parametern arbeiten
      Erkläre, warum Variablen, die innerhalb einer Funktion erstellt werden, nur während ihres Aufrufs existieren, wie Python einen Namen findet und warum das Ändern eines Parameters die Variable des aufrufenden Codes nicht ändert.
    • Globale Variablen mit Bedacht verwenden
      Lies globale Werte sicher, verstehe den Fehler bei der Zuweisung an einen globalen Namen, verwende die global-Anweisung richtig und bevorzuge Parameter und Rückgabewerte.
  5. Beschreibe Funktionen mit Docstrings, zerlege ein Problem in kleine, gut benannte Funktionen und erstelle und prüfe ein Programm Funktion für Funktion.
    • Funktionen mit Docstrings dokumentieren
      Schreibe einzeilige und mehrzeilige Docstrings nach den üblichen Konventionen und lies sie mit help().
    • Ein Problem in Funktionen zerlegen
      Zerlege eine Aufgabe in Schritte, mache jeden Schritt zu einer Funktion mit klaren Eingaben und Ausgaben und organisiere das Programm um eine main-Funktion.
    • Ein Programm Funktion für Funktion erstellen und prüfen
      Entwickle ein Programm in kleinen Schritten, teste jede Funktion mit Eingaben, deren Ergebnisse du kennst, und finde mit Tracebacks und vorübergehenden Ausgaben Fehler innerhalb von Funktionen.

Python-Funktionen einfach erklärt

5 Kapitel

1

Eigene Funktionen definieren und aufrufen

Eine Funktion gibt einem nützlichen Stück Code einen Namen, sodass du es immer ausführen kannst, wenn die Aufgabe anfällt. Die Definition zu schreiben und einen Aufruf durchzuführen sind getrennte Schritte. Dieser Unterschied erklärt, warum manche Programme enden, ohne etwas anzuzeigen. Du schreibst korrekt eingerückte Definitionen, wählst gut lesbare Namen und verfolgst den Ablauf, wenn eine Funktion eine andere aufruft und dann zum aufrufenden Code zurückkehrt.

1.1 Eine Funktion definieren und aufrufen

Eine Funktion ist ein benannter Codeblock, der eine Aufgabe erfüllt. Eingebaute Funktionen wie print() und input() stellen dir bereits nützliche Aufgaben zum Aufrufen bereit; mit def kannst du eigene erstellen. Ein guter Name macht aus mehreren Arbeitszeilen einen Aufruf, der beschreibt, was getan werden soll.

Kopf und Körper schreiben
def greet():
    print("Hello!")
    print("Welcome to Python.")

greet()
greet()

Der Kopf beginnt mit def, danach folgen der Name, runde Klammern und ein Doppelpunkt. Die eingerückten Zeilen bilden den Körper. Verwende vier Leerzeichen pro Einrückungsebene. Die nicht eingerückten greet()-Zeilen liegen außerhalb der Funktion und sind daher Aufrufe im Hauptprogramm.

Wenn Python die Definition erreicht, erstellt es die Funktion und gibt ihr den Namen greet. Noch wird keine der beiden Meldungen ausgegeben. Der erste Aufruf beginnt bei der ersten Zeile des Körpers und gibt „Hello!“ gefolgt von „Welcome to Python.“ aus. Der zweite Aufruf beginnt den Körper erneut und gibt dieselben zwei Zeilen aus. Insgesamt entstehen vier Ausgabezeilen.

Ein Name und ein Aufruf sind verschieden

Die runden Klammern in greet() machen daraus einen Aufruf, obwohl diese Funktion keine Eingaben braucht. Eine Zeile, die nur greet enthält, verweist auf die Funktion und führt nichts aus. print(greet) zeigt eine Beschreibung des Funktionsobjekts einschließlich einer Speicheradresse an; es führt die Begrüßung nicht aus.

Python muss eine Definition ausgeführt haben, bevor ein Aufruf ihren Namen verwendet. Beginnt eine Datei mit greet() und definiert greet erst danach, löst die erste Zeile NameError: name 'greet' is not defined aus. Setze die Definition über den Aufruf auf Modulebene.

Namen wählen, die die Aufgabe erklären

Verwende kleingeschriebene Wörter, die durch Unterstriche verbunden sind, etwa print_receipt oder convert_to_miles. Namen dürfen Buchstaben, Ziffern und Unterstriche enthalten, aber nicht mit einer Ziffer beginnen oder ein reserviertes Wort wie return sein. Die Groß- und Kleinschreibung wird beachtet: greet und Greet sind verschiedene Namen.

Halte eingebaute Namen verfügbar. Nach input = "yes" verweist der Name input auf Text, daher löst input("Name? ") den Fehler TypeError: 'str' object is not callable aus. Nennst du die Variable answer, bleibt die eingebaute Funktion zugänglich.

Zuerst die Struktur korrigieren

Ein fehlender Doppelpunkt im Kopf führt zu SyntaxError: expected ':'. Ein leerer oder nicht eingerückter Körper führt zu einem IndentationError. Auch eine geplante Funktion braucht eine Anweisung; pass ist ein Platzhalter, der nichts tut:

def print_receipt():
    pass

print_receipt()

Dieses Programm läuft ohne Ausgabe. Der Aufruf erreicht pass und dann das Ende des Körpers. Ersetze den Platzhalter durch die eigentliche Aufgabe, sobald du sie implementieren willst. Wenn eine Zeile zum Körper gehören sollte, aber zum falschen Zeitpunkt ausgeführt wird, prüfe ihre Einrückung, bevor du den Aufruf änderst.

Wichtige Erkenntnisse

  • Definiere eine Funktion mit def name(): und einem eingerückten Körper.
  • Eine Definition erstellt die Funktion; runde Klammern machen daraus einen Aufruf, der sie ausführt.
  • Führe die Definition einer Funktion aus, bevor du einen Aufruf tätigst, der ihren Namen benötigt.
  • Wähle beschreibende kleingeschriebene Namen mit Unterstrichen und vermeide eingebaute Namen.
  • Verwende pass, wenn eine geplante Funktion einen gültigen Platzhalterkörper braucht.

1.2 Den Programmablauf nachvollziehen

Ein Programm mit Funktionen führt nicht jeden Körper in der Reihenfolge aus, in der er auf der Seite steht. Ein Aufruf ändert den Programmablauf: Python wechselt in die aufgerufene Funktion, beendet deren Arbeit und setzt den aufrufenden Code direkt nach diesem Aufruf fort.

Einen Aufruf in einen weiteren Aufruf verfolgen
def line():
    print("----------")

def banner():
    line()
    print("  REPORT")
    line()

print("Start")
banner()
print("End")

Zuerst definiert Python line und banner. Keiner der beiden Körper wird ausgeführt. Die nächste Anweisung gibt „Start“ aus. Der Aufruf von banner() wechselt in dessen Körper, dessen erste Anweisung line() aufruft.

Python wechselt nun in line, gibt „----------“ aus und erreicht das Ende. Es kehrt zur nächsten Anweisung in banner zurück, die „ REPORT“ ausgibt. Der zweite Aufruf von line() gibt eine weitere gestrichelte Linie aus. Schließlich endet banner, sodass das Hauptprogramm fortgesetzt wird und „End“ ausgibt.

Die Ausgabe lautet:

Start
----------
  REPORT
----------
End
Nicht abgeschlossene Aufrufe verfolgen

Während line läuft, wartet banner auf dessen Ende. Auch das Hauptprogramm wartet auf banner. Python erfasst diese nicht abgeschlossenen Aufrufe im Aufrufstapel. Der innerste aktive Aufruf endet zuerst, und jeder aufrufende Code wird bei seiner eigenen nächsten Anweisung fortgesetzt.

Nummeriere für eine Ablaufverfolgung auf Papier die Zeilen des Programms. Notiere eine Zeile eines Funktionskörpers erst, wenn der Ablauf sie durch einen Aufruf erreicht. Markiere bei jedem Aufruf, wo es weitergeht. Schreibe die Ausgabe auf, wenn das zugehörige print ausgeführt wird, und behalte Leerzeichen und Zeilenumbrüche bei. So trennst du den Weg durch den Code von der erzeugten Ausgabe.

Hilfsfunktionen definieren, bevor sie gebraucht werden

Die Definition einer Hilfsfunktion darf unter der Definition der aufrufenden Funktion stehen:

def show_report():
    draw_line()
    print("Ready")

def draw_line():
    print("====")

show_report()

Das funktioniert, weil beide Definitionen ausgeführt wurden, bevor der abschließende Aufruf in show_report wechselt. Python sucht draw_line, wenn der Körper die Funktion tatsächlich aufruft. Würde show_report() über def draw_line(): verschoben, würde der Aufruf fehlschlagen, sobald er die fehlende Hilfsfunktion verwenden will.

Wiederholte Aufrufe beginnen von vorn

Ein Aufruf innerhalb einer Schleife wechselt bei jeder Wiederholung in den Körper:

for i in range(3):
    line()

Mit der ersten Definition von line gibt dies die gestrichelte Linie dreimal aus. Die Funktion beginnt bei jedem Aufruf mit ihrer ersten Anweisung im Körper.

Schlägt ein Aufruf fehl, zeigt Python einen Traceback. Seine letzte Zeile nennt den Fehlertyp und die Meldung. Die Aufrufeinträge darüber reichen vom äußersten noch nicht abgeschlossenen Aufruf bis zur Zeile, in der der Fehler auftrat. Lies zuerst den letzten Fehler und prüfe dann die innerste Zeile und den zugehörigen Aufruf. So findest du sowohl die fehlgeschlagene Operation als auch den Weg, auf dem sie ihre Daten erhielt.

Wichtige Erkenntnisse

  • Verfolge die Anweisungen der Funktionskörper in der Reihenfolge der Aufrufe und notiere die Ausgabe, wenn das jeweilige print ausgeführt wird.
  • Der Aufrufstapel erfasst nicht abgeschlossene Aufrufe und die Stellen, an denen es weitergeht.
  • Eine Hilfsfunktion kann unter der aufrufenden Funktion definiert werden, wenn ihre Definition vor ihrem Aufruf ausgeführt wird.
  • Lies den letzten Fehler eines Tracebacks und prüfe dann die fehlerhafte Zeile und den zugehörigen Aufruf.
2

Informationen an Funktionen übergeben

Parameter ermöglichen es einer Funktion, unterschiedliche Eingaben zu verarbeiten, ohne ihren Körper umzuschreiben. Der aufrufende Code liefert Argumente und Python verbindet diese Werte mit den Parameternamen, bevor der Körper beginnt. Du ordnest Argumente nach Position und Namen zu, kombinierst diese Formen richtig und wählst Standardwerte für häufige Fälle. Außerdem siehst du, warum ein Standardwert bei der Ausführung der Definition erstellt wird und wie sich das auf eine Liste als Standardwert auswirkt.

2.1 Parameter und Positionsargumente verwenden

Eine Funktion lässt sich für verschiedene Eingaben wiederverwenden, wenn ihr Kopf die benötigten Werte benennt. Diese Namen sind Parameter. Der aufrufende Code liefert Argumente, also die tatsächlich für einen bestimmten Aufruf verwendeten Werte.

Werte Namen zuordnen
def rectangle_area(width, height):
    print("Area:", width * height)

rectangle_area(4, 2.5)
rectangle_area(3, 7)

Die Parameter sind width und height. Im ersten Aufruf sind die Argumente 4 und 2.5. Positionsargumente werden von links nach rechts zugeordnet: width erhält 4 und height erhält 2,5. Der Körper gibt „Area: 10.0“ aus. Der nächste Aufruf gibt denselben Parameternamen neue Werte und gibt „Area: 21“ aus.

Jeder Parameter wirkt innerhalb dieses Aufrufs als Variable. Du musst width und height nicht vorher zuweisen; der Aufruf liefert ihre Werte. Eine Funktion ohne Parameter braucht trotzdem leere runde Klammern in ihrer Definition und in ihren Aufrufen.

Die Reihenfolge kann die Bedeutung ändern
def describe_pet(animal, name):
    print(name, "is a", animal)

describe_pet("cat", "Milo")
describe_pet("Milo", "cat")

Der erste Aufruf gibt „Milo is a cat“ aus. Der zweite gibt „cat is a Milo“ aus. Beide Aufrufe sind gültiges Python, daher weist kein Fehler auf die vertauschte Bedeutung hin. Lies die Reihenfolge im Kopf, bevor du Positionsargumente wählst, besonders wenn mehrere Parameter dieselbe Art von Wert annehmen.

Argumente können Ausdrücke sein

Python wertet jeden Argumentausdruck aus, bevor der Körper beginnt. Bei side = 6 übergibt der Aufruf rectangle_area(side, side) zweimal 6 und gibt „Area: 36“ aus. Der Variablenname im aufrufenden Code muss mit keinem der Parameternamen übereinstimmen. Der Aufruf rectangle_area(side + 1, 2) übergibt 7 und 2; er übergibt nicht den Text „side + 1“.

Einen Fehler bei der Argumentanzahl lesen

Jeder Parameter ohne Standardwert braucht ein Argument. Für die obige Flächenfunktion gilt:

AufrufWas schiefläuft
rectangle_area(4)height fehlt.
rectangle_area(4, 2, 1)Für zwei Parameter wurden drei Argumente übergeben.

Der erste Aufruf löst TypeError: rectangle_area() missing 1 required positional argument: 'height' aus. Der zweite löst TypeError: rectangle_area() takes 2 positional arguments but 3 were given aus. Prüfe den Kopf der genannten Funktion und zähle dann, wie der Aufruf ihre Parameter belegt.

Die für die Aufgabe benötigte Art von Wert übergeben

Python schreibt keinen Datentyp vor, nur weil ein Parameter width heißt. rectangle_area("4", 2) gibt „Area: 44“ aus, weil die Multiplikation von Text mit einer ganzen Zahl diesen Text wiederholt. Da input() Text zurückgibt, wandle numerische Eingaben vor der Übergabe um:

width = float(input("Width: "))
rectangle_area(width, 2)

Hier wandelt float() den eingegebenen Text in eine Zahl um, bevor die Flächenfunktion ihn erhält.

Wichtige Erkenntnisse

  • Ein Parameter ist ein Name im Kopf; ein Argument ist ein Wert, den ein Aufruf liefert.
  • Positionsargumente belegen Parameter von links nach rechts.
  • Python wertet Argumentausdrücke aus, bevor der Funktionskörper ausgeführt wird.
  • Jeder erforderliche Parameter braucht einen Wert; fehlende oder überzählige Argumente lösen TypeError aus.
  • Wandle numerische Eingaben aus Text um, bevor du sie für numerische Berechnungen übergibst.

2.2 Funktionen mit Schlüsselwortargumenten aufrufen

Ein Schlüsselwortargument nennt im Aufruf den Parameter, für den es bestimmt ist. Das macht einen Aufruf leichter lesbar, wenn mehrere Werte verwechselt werden könnten. Python ordnet das Schlüsselwort dem Namen im Kopf zu, statt seine Position zu verwenden.

Nach Namen zuordnen
def describe_pet(animal, name):
    print(name, "is a", animal)

describe_pet(name="Milo", animal="cat")
describe_pet(animal="cat", name="Milo")

Beide Aufrufe geben „Milo is a cat“ aus. Die Reihenfolge der Schlüsselwortargumente kann sich ändern, weil jeder Wert den Parameter benennt, den er belegt. Nach demselben Prinzip ist rectangle_area(width=4, height=2.5) lesbar, ohne nachzusehen, welche Abmessung zuerst kam.

Ein Schlüsselwort ist keine neue Variable im aufrufenden Code. In describe_pet(name="Milo", animal="cat") leitet name= den Wert „Milo“ an den Parameter. Es weist „Milo“ keiner Variablen namens name auf Modulebene zu. Schreibe Schlüsselwortargumente nach dem üblichen Python-Stil ohne Leerzeichen um =.

Positions- und Schlüsselwortargumente kombinieren
describe_pet("cat", name="Milo")

Das erste Argument belegt animal anhand seiner Position. Das Schlüsselwort belegt name, sodass jeder Parameter genau einen Wert erhält. Positionsargumente müssen zuerst stehen. Der Aufruf describe_pet(name="Milo", "cat") wird mit SyntaxError: positional argument follows keyword argument abgelehnt.

Um einen gemischten Aufruf zu prüfen, belege die Positionen zunächst von links nach rechts und ordne dann die Schlüsselwörter zu. Prüfe, dass keine Position zweimal belegt wird und keine erforderliche Position leer bleibt.

Doppelte oder unbekannte Schlüsselwörter korrigieren
AufrufDiagnose
describe_pet("cat", animal="dog")animal erhält sowohl „cat“ als auch „dog“.
describe_pet(animal="cat", nmae="Milo")Der Kopf hat keinen Parameter namens nmae.

Die doppelte Belegung löst TypeError: describe_pet() got multiple values for argument 'animal' aus. Der Schreibfehler löst TypeError: describe_pet() got an unexpected keyword argument 'nmae' aus. Vergleiche die Namen Zeichen für Zeichen; auch Groß- und Kleinschreibung sind wichtig. Die Reihenfolge der Argumente zu ändern behebt keine doppelte Zuweisung an einen Parameter.

Schlüsselwörter in eingebauten Funktionen erkennen
print("a", "b", "c", sep="-")
print("Loading", end="...")
print("done")

Die erste Zeile gibt „a-b-c“ aus. sep liefert den Text zwischen den angezeigten Werten. Die nächsten beiden Aufrufe erzeugen „Loading...done“ in einer Zeile: end ersetzt den üblichen Zeilenumbruch nach „Loading“.

Einige eingebaute Funktionen akzeptieren ebenfalls benannte Argumente; zum Beispiel ergibt round(3.14159, ndigits=2) den Wert 3,14. Verwende die für die aufgerufene Funktion dokumentierten Parameternamen. Ein selbst erfundenes beschreibendes Wort wird nicht erkannt, nur weil es zur Aufgabe zu passen scheint.

Wichtige Erkenntnisse

  • Schlüsselwortargumente werden Parameternamen zugeordnet, daher kann ihre Reihenfolge variieren.
  • Setze Positionsargumente vor Schlüsselwortargumente.
  • Belege jeden Parameter genau einmal und schreibe jedes Schlüsselwort exakt.
  • Ein Schlüsselwort in einem Aufruf ordnet einen Wert zu; es weist keiner Variablen des aufrufenden Codes einen Wert zu.
  • Bei print steuert sep die Trennzeichen und end den Abschluss.

2.3 Parametern Standardwerte geben

Ein Standardwert ermöglicht es einem Aufruf, ein Argument wegzulassen, wenn eine häufige Wahl geeignet ist. Schreibe den Standardwert im Kopf neben seinen Parameter. Ein übergebenes Argument setzt den Standardwert für diesen Aufruf außer Kraft.

Einen Parameter optional machen
def greet(name, greeting="Hello"):
    print(greeting + ",", name + "!")

greet("Ana")
greet("Ana", "Welcome")
greet("Ana", greeting="Hi")

Die Ausgabe lautet „Hello, Ana!“, „Welcome, Ana!“ und „Hi, Ana!“. name ist erforderlich, weil es keinen Standardwert hat. greet() löst daher einen TypeError aus, obwohl der andere Parameter optional ist.

In diesen Köpfen stehen erforderliche Parameter vor Parametern mit Standardwerten. def greet(greeting="Hello", name): ist ungültig. Python meldet einen Syntaxfehler, weil ein Parameter ohne Standardwert auf einen mit Standardwert folgt. Verschiebe name vor greeting, damit er erforderlich bleibt.

Eine optionale Einstellung ändern
def order_coffee(size, shots=1, milk="none"):
    print(size, "coffee,", shots, "shot(s), milk:", milk)

order_coffee("large", milk="oat")

Dies gibt „large coffee, 1 shot(s), milk: oat“ aus. Das Schlüsselwort erreicht milk, während shots bei 1 bleibt. Ein Positionsaufruf order_coffee("medium", 2) ändert shots und belässt milk bei „none“. Die Zuordnung nach Position überspringt keinen optionalen Parameter, um den nächsten zu erreichen.

Auch eingebaute Funktionen bieten Standardwerte: Ein gewöhnliches print() trennt Werte durch ein Leerzeichen und endet mit einem Zeilenumbruch. round(3.7) ergibt die ganze Zahl 4; round(3.14159, 2) fordert zwei Nachkommastellen an und ergibt 3,14.

Standardwerte werden bei der Ausführung der Definition erstellt
rate = 0.05

def price_with_tax(price, tax_rate=rate):
    return price * (1 + tax_rate)

rate = 0.08
print(price_with_tax(100))
print(price_with_tax(100, rate))

Der Standardwert speichert 0,05, wenn def ausgeführt wird. Eine spätere Änderung von rate ändert diesen gespeicherten Standardwert nicht. Die Aufrufe geben „105.0“ und „108.0“ aus: Nur der zweite übergibt ausdrücklich den neuen Satz.

Versehentlich gemeinsam genutzte Listen vermeiden

Eine Liste enthält Elemente, und append fügt derselben Liste ein Element hinzu. Bei einer Liste als Standardwert teilen sich alle Aufrufe, die das Argument auslassen, diese Liste:

def add_item(item, basket=[]):
    basket.append(item)
    print(basket)

add_item("apple")
add_item("pear")

Dies gibt ['apple'] und dann ['apple', 'pear'] aus. Die Standardliste wurde einmal erstellt, nicht einmal pro Aufruf. Um für jedes weggelassene Argument eine neue Liste zu erstellen, verwende None als Signal:

def add_item(item, basket=None):
    if basket is None:
        basket = []
    basket.append(item)
    print(basket)

Nun geben diese beiden Aufrufe ['apple'] und ['pear'] aus. Eine ausdrücklich übergebene Liste wird weiterhin wie übergeben verwendet. Beschreibe optionale Parameter und ihre Standardwerte im Docstring, damit der aufrufende Code weiß, welche Werte beim Weglassen gewählt werden.

Wichtige Erkenntnisse

  • Für ein weggelassenes optionales Argument gilt der Standardwert; ein ausdrücklich übergebenes Argument setzt ihn außer Kraft.
  • Setze erforderliche Parameter vor Parameter mit Standardwerten.
  • Verwende ein Schlüsselwort, um eine spätere Option zu ändern, ohne vorherige optionale Positionen zu belegen.
  • Standardwertausdrücke werden einmal ausgewertet, wenn def ausgeführt wird.
  • Eine veränderliche Liste als Standardwert wird von Aufrufen gemeinsam genutzt, die das Argument auslassen.
  • Verwende None und erstelle im Körper eine Liste, wenn für jedes weggelassene Argument eine neue Liste gebraucht wird.
3

Ergebnisse als Rückgabewerte zurückgeben

Eine Rechnung wird nützlicher, wenn ihr Ergebnis in eine weitere Rechnung, eine Bedingung oder eine Anzeige einfließen kann. Die return-Anweisung ermöglicht dies, indem sie einen Wert an den aufrufenden Code zurückgibt. Du unterscheidest Rückgabe und Ausgabe, verfolgst das erste ausgeführte return und prüfst Pfade, die ohne nutzbares Ergebnis enden könnten. Danach erstellst du boolesche Funktionen, schließt Suchen korrekt ab und kombinierst die Ergebnisse kleiner Funktionen.

3.1 Einen Wert zurückgeben und verwenden

Eine Funktion kann dem aufrufenden Code ein Ergebnis zur Verwendung geben. Die return-Anweisung beendet den Aufruf und gibt dessen Wert zurück. An der aufrufenden Stelle steht der Aufruf für diesen Rückgabewert.

Ergebnisse speichern und kombinieren
def rectangle_area(width, height):
    return width * height

area = rectangle_area(4, 2.5)
print(area)
print(rectangle_area(3, 4) + rectangle_area(2, 5))

Der erste Aufruf gibt 10,0 zurück, das area zugewiesen wird; das erste print zeigt es an. In der letzten Zeile geben die beiden Aufrufe 12 und 10 zurück. Python addiert diese Ergebnisse und gibt „22“ aus. Die Funktion selbst enthält kein print und kann daher sowohl ein gespeichertes Ergebnis als auch einen Teil einer größeren Rechnung liefern.

Ein Rückgabewert kann auch in einer Bedingung geprüft oder an eine andere Funktion übergeben werden. So wird die Aufgabe der Berechnung von der Entscheidung des aufrufenden Codes getrennt, wie das Ergebnis verwendet wird.

Ausgabe und Rückgabe haben verschiedene Aufgaben
def double_print(n):
    print(n * 2)

result = double_print(5)
print(result)

Der Aufruf zeigt „10“ an, aber die angezeigte Zahl wird nicht als Ergebnis zurückgegeben. double_print erreicht das Ende seines Körpers und gibt daher None zurück. Die letzte Zeile gibt deshalb „None“ aus.

OperationWohin der Wert gelangt
print(value)Zeigt ihn für einen Menschen an.
return valueGibt ihn zur Verwendung im Programm an den aufrufenden Code zurück.

double_print(5) + 1 gibt zuerst „10“ aus und löst dann TypeError: unsupported operand type(s) for +: 'NoneType' and 'int' aus. Ersetze den Körper durch return n * 2, wenn der aufrufende Code die verdoppelte Zahl braucht. Eine Funktion, die nur eine Wirkung wie die Anzeige einer Meldung erzeugen soll, kann sinnvollerweise None zurückgeben; solche Funktionen heißen manchmal Funktionen ohne nutzbaren Rückgabewert. Eine Funktion mit einem nutzbaren Rückgabeergebnis heißt manchmal Funktion mit nutzbarem Rückgabewert.

Beim ersten ausgeführten return anhalten
def to_fahrenheit(celsius):
    return celsius * 9 / 5 + 32
    print("Converted")

print(to_fahrenheit(20))

Dies gibt „68.0“ aus. Das print im Körper wird nie erreicht, weil return den Aufruf bereits beendet hat. Entferne diese unerreichbare Anweisung oder verschiebe eine notwendige Aktion vor die Rückgabe. Die Umrechnung gibt Gleitkommazahlen zurück, weil / eine Gleitkommazahl erzeugt. Die Eingaben 100 und -40 ergeben 212,0 und -40,0.

Ein einzelnes return ohne Ausdruck beendet ebenfalls einen Aufruf und gibt None zurück. Jeder Funktionsaufruf hat ein Ergebnis, auch wenn kein nutzbarer Wert geliefert wurde.

Ergebnisse in einer Programmdatei sichtbar machen

Ein allein stehendes rectangle_area(3, 4) berechnet in einer Datei 12 und verwirft dann das ungenutzte Ergebnis. Verwende print(rectangle_area(3, 4)), um es anzuzeigen, oder weise es einer Variablen zu. Die interaktive Shell zeigt Ergebnisse von Ausdrücken außer None an, sodass ein erfolgreicher Versuch in der Shell anders aussehen kann als die Ausführung derselben Zeile in einer Datei.

Wichtige Erkenntnisse

  • return value beendet den Aufruf und lässt den Aufruf für diesen Wert stehen.
  • Die Ausgabe zeigt einen Wert an; die Rückgabe stellt ihn dem aufrufenden Code zur Verfügung.
  • Das Erreichen des Körperendes oder ein einzelnes return ergibt None.
  • Anweisungen nach einem ausgeführten return werden in diesem Aufruf nicht ausgeführt.
  • Verwende ein zurückgegebenes Ergebnis, indem du es speicherst, ausgibst, prüfst oder kombinierst.

3.2 Über verschiedene Pfade Werte zurückgeben und Ergebnisse kombinieren

Verschiedene Eingaben können verschiedene Antworten brauchen. Eine Funktion kann mehrere return-Anweisungen haben, aber ein Aufruf endet bei der ersten, die er ausführt. Verfolge den tatsächlichen Weg durch ihre Zweige und Schleifen, um das Ergebnis zu finden.

Überlappende Tests anordnen
def letter_grade(score):
    if score >= 90:
        return "A"
    if score >= 80:
        return "B"
    if score >= 70:
        return "C"
    return "F"

Für 85 ist der erste Test falsch und der zweite wahr. Die Funktion gibt „B“ zurück, ohne die übrigen Bedingungen zu prüfen. Für 42 sind alle drei Tests falsch, sodass das letzte return „F“ liefert. Getrennte if-Anweisungen funktionieren, weil jeder zutreffende Zweig den Aufruf beendet.

Hier muss der höchste Schwellenwert zuerst geprüft werden. Stünde score >= 70 zuerst, würde eine Punktzahl von 95 „C“ zurückgeben. Bei überlappenden Bereichen kann ein früh zutreffender allgemeiner Test eine spätere, genauere Antwort verdecken.

Den Pfad ohne zutreffenden Zweig abdecken
def sign(n):
    if n > 0:
        return "positive"
    elif n < 0:
        return "negative"
    return "zero"

Die letzte Zeile behandelt null. Ohne sie würde sign(0) das Ende erreichen und None zurückgeben. Verfolge eine Eingabe aus jedem Zweig und jeden verbleibenden Fall; würdest du nur positive und negative Eingaben testen, bliebe diese Lücke unentdeckt.

Einen booleschen Vergleich zurückgeben
def is_even(n):
    return n % 2 == 0

if is_even(10):
    print("Even")

Der Vergleich erzeugt bereits True oder False. is_even(10) gibt True zurück, während is_even(7) False zurückgibt. Verwende das Ergebnis direkt in einer Bedingung. Ein zusätzliches == True hilft dem Test nicht.

Eine Suche beenden, bevor kein Treffer gemeldet wird
def smallest_divisor(n):
    for d in range(2, n):
        if n % d == 0:
            return d
    return n

Für 91 scheitern die Kandidaten 2 bis 6, dann teilt 7 die Zahl ohne Rest. Die Rückgabe von 7 beendet sowohl die Schleife als auch die Funktion. Für 13 findet die Schleife keinen Teiler, sodass das letzte return 13 liefert.

Eine Primzahlprüfung muss die Suche nach einem erfolglosen Kandidaten fortsetzen können:

def is_prime(n):
    if n < 2:
        return False
    for d in range(2, n):
        if n % d == 0:
            return False
    return True

Das letzte True steht außerhalb der Schleife. Stünde es in einem else innerhalb der Schleife, würde die Funktion nach der Prüfung des ersten Kandidaten zurückkehren: 9 würde fälschlich akzeptiert, weil sie nicht durch 2 teilbar ist. Mit der korrigierten Funktion ergeben 9 und 1 den Rückgabewert False; 2, 7 und 97 ergeben True. Für 2 hat die Schleife keine Kandidaten und der Ablauf erreicht das letzte True.

Zwei Werte zurückgeben
def share(total, people):
    return total // people, total % people

each, left = share(17, 5)
print(each, left)

Der Aufruf gibt ein Tupel zurück, ein zusammengefasstes Ergebnis mit 3 und 2. Die Zuweisung entpackt es in zwei Namen, sodass die Ausgabe „3 2“ lautet. Die direkte Ausgabe des Aufrufs würde „(3, 2)“ zeigen. Die Anzahl der Namen muss mit der Anzahl der entpackten Werte übereinstimmen.

Aufrufe von innen nach außen kombinieren
def add(a, b):
    return a + b

def to_fahrenheit(celsius):
    return celsius * 9 / 5 + 32

print(to_fahrenheit(add(10, 15)))

add gibt zuerst 25 zurück. Dieser Wert wird zum Argument für to_fahrenheit, das 77,0 zurückgibt. Schließlich zeigt print „77.0“ an. Jeder innere Aufruf muss den Wert zurückgeben, den die nächste Funktion braucht.

Wichtige Erkenntnisse

  • Das erste ausgeführte return beendet einen Aufruf, ordne überlappende Tests also sorgfältig an.
  • Sieh für jeden Eingabepfad, den die Funktion behandeln muss, ein nutzbares Ergebnis vor.
  • Eine boolesche Funktion kann einen Vergleich direkt zurückgeben.
  • Gib innerhalb einer Suchschleife ein gefundenes Ergebnis zurück; melde erst dann keinen Treffer, wenn alle Kandidaten gescheitert sind.
  • Durch Kommas getrennte Rückgabewerte bilden ein Tupel, das entpackt werden kann.
  • Bei verschachtelten Aufrufen wird das innere Ergebnis zum Argument des äußeren Aufrufs.
4

Den Gültigkeitsbereich von Variablen kennen: lokal und global

Ein Name innerhalb einer Funktion kann genauso aussehen wie ein Name außerhalb und sich dennoch auf eine andere Variable beziehen. Der Gültigkeitsbereich gibt an, wo ein Name verwendet werden kann, und Zuweisungen bestimmen mit, welchen Namen Python meint. Du verfolgst Parameter und andere lokale Variablen während eines Aufrufs, unterscheidest eine erneute Zuweisung von der Änderung einer gemeinsam referenzierten Liste und liest globale Einstellungen. Außerdem behebst du einen häufigen Fehler beim Gültigkeitsbereich und machst veränderliche Werte in Aufrufen sichtbar.

4.1 Mit lokalen Variablen und Parametern arbeiten

Der Gültigkeitsbereich beschreibt, wo ein Name verwendet werden kann. Parameter und Namen, denen innerhalb einer Funktion Werte zugewiesen werden, sind lokal für den jeweiligen Aufruf der Funktion. Der aufrufende Code und eine Funktion können ähnliche Namen verwenden, ohne dieselben lokalen Variablen zu teilen.

Lokale Namen innerhalb ihres Aufrufs halten
def make_greeting():
    message = "Hi"
    print(message)

make_greeting()

Dies gibt „Hi“ aus. Ein zusätzliches print(message) nach dem Aufruf löst NameError: name 'message' is not defined aus: Der lokale Name ist dort nicht verfügbar. Um den Wert dem aufrufenden Code verfügbar zu machen, gib ihn zurück und speichere ihn:

def make_greeting():
    return "Hi"

message = make_greeting()
print(message)

Das message auf Modulebene ist eine neue Variable des aufrufenden Codes, die den Rückgabewert erhält. Die Funktion macht ihre eigenen lokalen Namen nicht außerhalb sichtbar.

Jeder Aufruf erhält neue lokale Variablen. Wenn ein Körper count = 0 setzt, 1 addiert und den Wert ausgibt, geben zwei Aufrufe „1“ und „1“ aus. Der zweite Aufruf setzt nicht mit dem Zählerstand des ersten fort. Auch verschiedene Funktionen können lokale Namen wie total unabhängig voneinander verwenden.

Verdeckung und Namenssuche verfolgen
x = 10

def show():
    x = 5
    print(x)

show()
print(x)

Die Ausgabe lautet „5“ und dann „10“. Das lokale x verdeckt das globale x innerhalb von show; die Zuweisung ändert den Wert auf Modulebene nicht. Eine globale Variable gehört zum Gültigkeitsbereich auf Modulebene der Datei. Gewöhnliche Zuweisungen außerhalb von Funktionen erstellen globale Variablen.

Bei einer auf Modulebene der Datei definierten Funktion sucht Python einen Namen unter ihren lokalen Namen, dann unter den globalen Namen der Datei und dann unter eingebauten Namen wie print. Der erste Treffer wird verwendet. Lokale und globale Namen sind daher verschiedene Stellen, die du prüfen kannst, wenn ein Wert falsch erscheint.

Die erneute Zuweisung an einen Parameter lässt den Namen des aufrufenden Codes unverändert
def add_bonus(points):
    points = points + 10
    print(points)

score = 50
add_bonus(score)
print(score)

points beginnt mit dem Wert 50. Die lokale erneute Zuweisung macht daraus 60, sodass die erste Ausgabe „60“ lautet. Das score des aufrufenden Codes ist weiterhin 50. Um diesen Namen ausdrücklich zu aktualisieren, verwende eine Funktion, die points + 10 zurückgibt, und schreibe dann score = add_bonus(score).

Eine Liste zu ändern ist eine andere Operation

Auf eine Liste kann über zwei Namen verwiesen werden:

def add_guest(guests, name):
    guests.append(name)

party = ["Ana"]
add_guest(party, "Ben")
print(party)

Der Parameter guests und die Variable party des aufrufenden Codes verweisen auf dieselbe Liste. append ändert den Inhalt dieser Liste, daher lautet die Ausgabe „['Ana', 'Ben']“. Eine Zuweisung guests = [] innerhalb der Funktion würde dagegen nur den lokalen Namen auf eine neue Liste verweisen lassen; party würde weiterhin auf die ursprüngliche Liste verweisen. Frag dich beim Nachvollziehen eines Listenarguments, ob die Zeile das gemeinsam referenzierte Objekt ändert oder nur einem lokalen Namen einen neuen Wert zuweist.

Wichtige Erkenntnisse

  • Parameter und Namen, denen innerhalb einer Funktion Werte zugewiesen werden, sind lokal für ihren Aufruf.
  • Jeder Aufruf erhält neue lokale Variablen; Rückgabewerte tragen Ergebnisse nach außen.
  • Ein lokaler Name kann einen globalen verdecken, ohne den globalen Wert zu ändern.
  • Eine erneute Zuweisung an einen Parameter lässt die Variable des aufrufenden Codes unverändert.
  • Eine Veränderung einer gemeinsam referenzierten Liste ändert die Liste, die der aufrufende Code sieht.

4.2 Globale Variablen mit Bedacht verwenden

Eine Funktion kann einen globalen Namen ohne Deklaration lesen. Für die Zuweisung an einen Namen in ihrem Körper gilt eine andere Regel. Werden diese Operationen verwechselt, entsteht häufig ein UnboundLocalError.

Eine feste Einstellung lesen
TAX_RATE = 0.25

def tax(amount):
    return amount * TAX_RATE

print(tax(80))

Die Ausgabe lautet „20.0“. amount ist lokal; TAX_RATE wird aus den globalen Namen der Datei gelesen. Großbuchstaben kennzeichnen nach Konvention eine Konstante und zeigen an, dass das Programm die Einstellung unverändert lassen soll. Python erzwingt diese Konvention nicht.

Eine Zuweisung macht einen Namen im gesamten Körper lokal
total = 0

def add_to_total(amount):
    total = total + amount

add_to_total(5)

Die Zuweisung macht total in ganz add_to_total lokal. Um die rechte Seite zu berechnen, versucht Python, diesen lokalen Namen zu lesen, bevor er einen Wert hat. Es greift nicht auf das globale total zurück. Der Aufruf löst UnboundLocalError: cannot access local variable 'total' where it is not associated with a value aus.

Die Entscheidung beruht auf dem ganzen Körper, nicht nur auf bereits ausgeführten Zeilen. Auch ein Körper mit print(count) gefolgt von count = 10 behandelt count in der print-Zeile als lokal. Ein globales count kann den fehlenden lokalen Wert nicht liefern.

Eine beabsichtigte globale Zuweisung deklarieren
total = 0

def add_to_total(amount):
    global total
    total = total + amount

add_to_total(5)
add_to_total(7)
print(total)

Nun beziehen sich sowohl das Lesen als auch die Zuweisung auf den globalen Namen, sodass die Ausgabe „12“ lautet. Setze global total vor jede Verwendung von total in der Funktion. Die Verwendung des Namens vor seiner Deklaration ist ein Syntaxfehler.

Eine Deklaration allein erstellt keinen Wert. Eine nachfolgende Zuweisung kann eine globale Variable erstellen, die noch nicht existierte: Ein Funktionskörper mit global level und danach level = 1 erstellt beim Aufruf das globale level.

Die Änderung durch Eingaben und ein Ergebnis zeigen

Dieselbe laufende Summe lässt sich mit einer ausdrücklichen Schnittstelle schreiben:

def add_to_total(total, amount):
    return total + amount

total = 0
total = add_to_total(total, 5)
total = add_to_total(total, 7)
print(total)

Auch dies gibt „12“ aus. Jeder Aufruf zeigt, dass der alte Wert übergeben wird, und die Zuweisung zeigt, wohin der neue Wert gelangt. Du kannst add_to_total(10, 3) für sich prüfen, ohne vorher einen verborgenen globalen Zustand einzurichten. Wenn mehrere Funktionen denselben globalen Wert ändern, hängt ihr Verhalten von der Reihenfolge ihrer Ausführung ab.

Operation innerhalb einer FunktionDeklaration nötig?
Eine globale Einstellung lesenNein.
Einem globalen Namen einen neuen Wert zuweisenglobal name vor der Verwendung.
An eine vorhandene globale Liste anhängenNein; dem Namen wird kein neuer Wert zugewiesen.

Das Lesen einer gemeinsam referenzierten Liste und das Ändern ihres Inhalts nutzen die vorhandene Referenz. Den globalen Namen durch eine andere Liste zu ersetzen ist eine Zuweisung, daher gilt die Zuweisungsregel.

Wichtige Erkenntnisse

  • Lies einen globalen Namen ohne besondere Deklaration.
  • Eine Zuweisung irgendwo in einer Funktion macht den Namen lokal, sofern er nicht als global deklariert wird.
  • Das Lesen eines lokalen Namens ohne zugewiesenen Wert löst UnboundLocalError aus.
  • Setze global name vor die Verwendung eines Namens, dem die Funktion bewusst global einen neuen Wert zuweist.
  • Bevorzuge Parameter und Rückgabewerte, wenn ein veränderlicher Wert ausdrücklich übergeben werden kann.
  • Für das Verändern einer Liste und die erneute Zuweisung ihres Namens gelten unterschiedliche Regeln.
5

Programme mit Funktionen dokumentieren und gestalten

Gute Funktionen brauchen klare Aufgaben und korrekten Code. Wer eine Funktion aufruft, sollte sehen können, was sie benötigt, was sie zurückgibt und welche Wirkung sie hat, ohne jede Zeile ihres Körpers zu studieren. Du schreibst Docstrings, zerlegst ein vollständiges Programm in Hilfsfunktionen und verbindest diese durch eine kleine main-Funktion. Anschließend prüfst du die einzelnen Teile anhand erwarteter Ergebnisse, Eingaben an Grenzen und der Hinweise in einem Traceback.

5.1 Funktionen mit Docstrings dokumentieren

Wer eine Funktion aufruft, muss ihre Aufgabe kennen, ohne ihre gesamte Implementierung zu lesen. Ein Docstring liefert diese Beschreibung. Python erkennt eine Zeichenkette als Docstring der Funktion, wenn sie die erste Anweisung im Körper ist.

Zuerst eine kurze Beschreibung schreiben
def to_fahrenheit(celsius):
    """Convert a temperature from degrees Celsius to degrees Fahrenheit."""
    return celsius * 9 / 5 + 32

print(to_fahrenheit.__doc__)

Die Ausgabe ist der Satz innerhalb der Anführungszeichen. Python speichert den Docstring in __doc__; die dreifachen Anführungszeichen gehören nicht zum gespeicherten Satz. help(to_fahrenheit) zeigt die Beschreibung zusammen mit der Signatur to_fahrenheit(celsius) an. Übergib den Funktionsnamen an help, ohne die Funktion aufzurufen.

Üblich sind dreifache doppelte Anführungszeichen, auch für einen einzeiligen Docstring. Beginne mit einer Aufforderung wie „Gib die Fläche eines Rechtecks zurück.“ und ende mit einem Punkt. Halte eine kurze Beschreibung und ihre schließenden Anführungszeichen in einer Zeile. Du musst den Funktionsnamen und die Parameterliste nicht wiederholen, weil die Hilfeanzeige sie bereits enthält.

Einzelheiten ergänzen, wenn sie gebraucht werden
def split_bill(total, people, tip_rate=0.2):
    """Return each person's share of a bill, including the tip.

    total: the bill before the tip
    people: the number of people sharing the bill
    tip_rate: the tip as a fraction of the bill (default 0.2)
    """
    return total * (1 + tip_rate) / people

Die erste Zeile nennt das Ergebnis. Eine Leerzeile trennt sie von Einzelheiten zu den Eingaben. Der Standardwert ist als 0,2 dokumentiert, als Anteil der Rechnung. Das verhindert, dass jemand beim Aufruf 20 als vorgesehenen Wert für 20 % Trinkgeld versteht. Die schließenden Anführungszeichen eines mehrzeiligen Docstrings stehen in einer eigenen Zeile.

Für split_bill(84, 4) wendet die Funktion den Standardwert für das Trinkgeld an und gibt 25,2 zurück. Wer die Funktion aufruft, kann vor der Wahl der Argumente erfahren, was die drei Eingaben bedeuten. Gib Einheiten an, wenn sie wichtig sind, und beschreibe Wirkungen wie Ausgaben, damit sich sowohl das Ergebnis als auch das sichtbare Verhalten vorhersagen lassen.

Dokumentation und Kommentare unterscheiden
FormHauptzweck
Erste Zeichenkette im KörperBeschreibt die Funktion für den aufrufenden Code und erscheint in help.
#-Kommentar im KörperErklärt jemandem, der die Implementierung liest, ein Detail des Codes.

Eine Zeichenkette nach einer Zuweisung oder einer anderen Anweisung im Körper ist kein Docstring der Funktion. Sie ist ein ungenutzter Zeichenkettenausdruck, und __doc__ ist None, wenn kein Docstring als erste Anweisung existiert. Auch ein #-Kommentar wird nicht zur Hilfebeschreibung.

Schreibe die Zusammenfassung, während du die Aufgabe der Funktion festlegst. Wenn der Satz mehrere voneinander unabhängige Aktionen braucht, überlege erneut, ob die Funktion aufgeteilt werden sollte. Wenn du Parameter, Standardwerte, Rückgabewerte oder Ausgaben änderst, aktualisiere gleichzeitig den Docstring; wer die Funktion aufruft, verlässt sich auf ihn als Teil der Schnittstelle.

Wichtige Erkenntnisse

  • Ein Funktions-Docstring ist die erste Anweisung in ihrem Körper.
  • Verwende dreifache doppelte Anführungszeichen und einen kurzen Aufforderungssatz, der mit einem Punkt endet.
  • Trenne bei längeren Beschreibungen die Zusammenfassung durch eine Leerzeile von den Einzelheiten.
  • Beschreibe wichtige Eingaben, Einheiten, Standardwerte, Ergebnisse und Wirkungen.
  • Lies gespeicherte Dokumentation mit help(name) oder name.__doc__.

5.2 Ein Problem in Funktionen zerlegen

Zerlegung bedeutet, eine Aufgabe in kleinere Aufgaben aufzuteilen. Jede Funktion übernimmt eine Aufgabe mit klaren Eingaben und einem klaren Ergebnis oder einer klaren Wirkung. Das Hauptprogramm kann sich dann wie eine kurze Folge benannter Schritte lesen.

Daten planen, bevor du die Körper schreibst

Unterscheide für ein Programm, das das arithmetische Mittel von Testergebnissen und eine Buchstabennote ausgibt, drei Arten von Arbeit: Ergebnisse einlesen, ein arithmetisches Mittel berechnen und eine Note wählen. Entscheide, was jede Hilfsfunktion erhält und zurückgibt. Belasse die Ausgabe in main, wo die Ergebnisse zusammenkommen.

def get_score(prompt):
    return float(input(prompt))

def average(a, b, c):
    return (a + b + c) / 3

def letter_grade(score):
    if score >= 90:
        return "A"
    if score >= 80:
        return "B"
    if score >= 70:
        return "C"
    return "F"

def main():
    first = get_score("Test 1: ")
    second = get_score("Test 2: ")
    third = get_score("Test 3: ")
    avg = average(first, second, third)
    print("Average:", round(avg, 1), "Grade:", letter_grade(avg))

main()

Bei den Ergebnissen 78, 92 und 85 gibt average den Wert 85,0 zurück. Dieses Ergebnis wird zum Argument für letter_grade, das „B“ zurückgibt. Die Ausgabe lautet „Average: 85.0 Grade: B“.

main koordiniert die Reihenfolge; es muss nicht wissen, wie letter_grade seine Antwort wählt. Eine Funktion anhand ihrer Aufgabe und Schnittstelle zu verwenden, ohne jede Anweisung im Körper zu verfolgen, heißt prozedurale Abstraktion. Du verwendest print bereits auf diese Weise.

Eine klare Schnittstelle für den aufrufenden Code schaffen

Die Schnittstelle einer Funktion besteht aus ihrem Namen, ihren Parametern, ihrem Rückgabeergebnis und ihrem dokumentierten Verhalten. average(a, b, c) benötigt drei Zahlen und gibt ihr arithmetisches Mittel zurück. Der aufrufende Code muss keine Eingabeaufforderung lesen oder ausgegebenen Text auffangen, um diese Zahl zu erhalten. Du kannst die Berechnung umschreiben und dabei die vereinbarten Eingaben und die Ausgabe beibehalten; vorhandene Aufrufe funktionieren weiterhin.

Verwende Namen wie calculate_total und print_receipt für Aktionen und is_even oder has_discount für boolesche Fragen. Parameternamen wie price und quantity erklären, welche Werte an die jeweilige Stelle gehören. Namen aus einem Buchstaben können geeignet sein, wenn ihre Bedeutung klar ist, wie bei den drei Eingaben von average.

Wiederholungen in Parameter überführen

Wenn mehrere Teile eines Programms verschiedene Titel zwischen denselben Zeilen aus Gleichheitszeichen ausgeben, mache den Titel zu einem Parameter von print_heading(title). Die wiederholte Struktur gehört in einen Körper, der wechselnde Text in die Aufrufe. Eine spätere Änderung der Zeilenlänge braucht dann nur eine Bearbeitung.

Wähle die Grenzen von Funktionen so, dass Aufgaben leichter zu verstehen oder wiederzuverwenden sind. Wenn jede Anweisung in einem langen main steht, werden die kleineren Aufgaben verdeckt. Jeden einfachen Ausdruck in eine einmal verwendete Hilfsfunktion aufzuteilen, kann Namen hinzufügen, ohne die Lesbarkeit zu verbessern. Eine nützliche Prüfung ist, ob ein kurzer Satz jede Aufgabe und ihre Eingaben und Ausgaben beschreiben kann.

Beende die Datei nach allen Definitionen mit dem tatsächlichen Aufruf main(). Ein Programm, das nur Definitionen enthält, erstellt seine Funktionen und endet, ohne ihre Körper auszuführen.

Wichtige Erkenntnisse

  • Zerlege die Aufgabe in Teilaufgaben mit benannten Eingaben und Ausgaben.
  • Trenne Berechnungen von Eingabe und Ausgabe, wenn sie wiederverwendet oder geprüft werden sollen.
  • Lass main die Hilfsfunktionen koordinieren und rufe main() nach den Definitionen auf.
  • Verwende Parameter für die Teile, die sich in wiederholtem Code ändern.
  • Eine stabile Schnittstelle ermöglicht es dem aufrufenden Code, eine Funktion unabhängig von ihrem Körper zu verwenden.
  • Wähle die Grenzen von Funktionen so, dass das Programm leichter zu verstehen ist.

5.3 Ein Programm Funktion für Funktion erstellen und prüfen

Wenn du mehrere Funktionen erstellst, bevor du eine davon ausführst, ist ein Fehler schwerer zu finden. Inkrementelle Entwicklung bedeutet, ein kleines Stück zu schreiben, es zu prüfen und dann das nächste hinzuzufügen. So behältst du ein funktionierendes Programm und begrenzt die Menge an neuem Code, die du untersuchen musst.

Beim Planen einen Funktionsplatzhalter verwenden

Ein Funktionsplatzhalter hat den vorgesehenen Kopf und einen Platzhalterkörper. Ein Docstring und pass halten die Definition gültig, aber die Funktion gibt None zurück, bis du sie implementierst. Eine feste Rückgabe kann helfen, die Ausgabe des aufrufenden Codes zu prüfen, ohne zu behaupten, dass die eigentliche Berechnung bereits funktioniert.

Beginne mit einer berechnenden Hilfsfunktion, deren Ergebnis du unabhängig ermitteln kannst. Sobald sie korrekt arbeitet, verbinde sie mit der nächsten Hilfsfunktion. Verschiebe interaktive Eingaben, bis sich die Berechnungen mit direkten Aufrufen prüfen lassen.

Erwartete Ergebnisse vor der Ausführung festlegen

Mit den Funktionen average und letter_grade haben die Ergebnisse 70, 75 und 72 ein arithmetisches Mittel von etwa 72,33; ihre erwartete Note ist also „C“. Prüfe beide Stufen:

print(average(70, 75, 72))
print(letter_grade(average(70, 75, 72)) == "C")

Die Ausgaben lauten „72.33333333333333“ und „True“. Der Vergleich prüft die erwartete Note direkt. Betrachtet man nur die Ausgabe eines Programms, ohne unabhängig ein Ergebnis zu erwarten, kann eine plausible falsche Antwort unentdeckt bleiben.

Grenzen ebenso wie gewöhnliche Eingaben testen

Teste für einen Schwellenwert von 90 die Werte 90 und 89,9. Die korrekte Notenfunktion gibt „A“ und „B“ zurück. Lautete ihre erste Bedingung score > 90, würde nur die Prüfung genau an der Grenze zeigen, dass 90 fälschlich durchfällt.

Beziehe einen typischen Wert, genaue Grenzen, nahe Werte und extreme Eingaben ein, die die Funktion behandeln soll. Bei der Notenfunktion prüfen 70 und 0 die unterste Grenze für eine bestandene Note und den abschließenden „F“-Pfad. Eine Prüfung wie print(letter_grade(85) == "B") ist einfach, weil die Funktion einen Wert entgegennimmt und ihr Ergebnis zurückgibt.

Den Traceback lesen und den ankommenden Wert untersuchen

Angenommen, main ruft letter_grade(input("Score: ")) auf. Die Eingabe „85“ übergibt eine Zeichenkette an einen Vergleich mit einer Zahl. Der letzte Fehler lautet TypeError: '>=' not supported between instances of 'str' and 'int'. Der Traceback weist auf den Vergleich innerhalb der Hilfsfunktion, während eine frühere Aufrufzeile auf main weist.

Der Fehler tritt beim Vergleich auf, die Korrektur gehört aber dorthin, wo die Eingabe vorbereitet wird: Wandle sie vor der Übergabe mit float() um. Ein vorübergehendes print("letter_grade got", score) in der ersten Zeile hilft, eine unerwartete Eingabe zu erkennen. Ist ihr Datentyp unklar, untersuche den aufrufenden Code und die dort verwendete Umwandlung. Entferne Debug-Ausgaben, nachdem der Fehler behoben ist.

Anzeichen mit wahrscheinlichen Ursachen verbinden
AnzeichenPrüfung
Ein Ergebnis ist NoneEin fehlendes return oder ein nicht abgedeckter Pfad.
Es erscheint keine WirkungEin fehlender Aufruf oder ein ungenutzter Rückgabewert.
Ein plausibles Ergebnis hat die falsche BedeutungVertauschte Argumente.
NameErrorEin falsch geschriebener oder nicht verfügbarer Funktions- oder Variablenname.

Führe nach der Korrektur einer Hilfsfunktion die Prüfungen für ihre betroffenen Pfade und den aufrufenden Code, der sie mit dem Programm verbindet, erneut aus.

Wichtige Erkenntnisse

  • Erstelle und prüfe eine Funktion, bevor du die nächste hinzufügst.
  • Berechne erwartete Ergebnisse unabhängig, bevor du sie mit Aufrufen vergleichst.
  • Teste genaue Grenzen und nahe Werte, um Vergleichsfehler zu finden.
  • Nutze den Traceback, um den Fehler und die zugehörigen Aufrufe zu finden.
  • Entferne vorübergehende Debug-Ausgaben, sobald das Problem behoben ist.

Python-Funktionen: Beispiele

5 Interaktive Lektionen

1

Eine Funktion schreiben und ihre Aufrufe verfolgen

10 Schritte
Erstelle eine wiederverwendbare Begrüßung und verfolge dann den aufrufenden Code durch seine Hilfsfunktion und zurück zum Hauptprogramm.
  1. 1
    EinführungEiner Aufgabe einen Namen geben

    Mit einer Funktion kannst du eine nützliche Aufgabe einmal schreiben und wählen, wann sie ausgeführt wird. Du beginnst mit einer Begrüßung und verfolgst dann einen Bericht, der eine Hilfsfunktion aufruft.

    Halte beim Lesen zwei Fragen auseinander: „Hat Python diese Funktion erstellt?“ und „Hat das Programm sie bereits aufgerufen?“ Das Erste macht den Namen verfügbar; das Zweite beginnt die Arbeit des Körpers. Dieser Unterschied erklärt, warum eine Datei voller Definitionen ohne Ausgabe enden kann.

  2. 2
    ErklärungDen wiederverwendbaren Körper schreiben
    def greet():
        print("Hello!")
        print("Welcome to Python.")
    

    Der Kopf verwendet def, einen Namen, runde Klammern und einen Doppelpunkt. Die beiden um vier Leerzeichen eingerückten Zeilen bilden den Körper. Python erstellt die Funktion, wenn diese Definition ausgeführt wird, aber noch wird keine der beiden print-Anweisungen ausgeführt.

    Die nächste nicht eingerückte Anweisung liegt außerhalb der Funktion. Die Einrückung zeigt Python, wo diese Aufgabe endet; sie ist Teil der Programmstruktur.

  3. 3
    BeispielDie Funktion zweimal ausführen

    Füge diese Zeilen nach der Definition hinzu:

    greet()
    greet()
    

    Der erste Aufruf wechselt in den Körper und gibt „Hello!“ gefolgt von „Welcome to Python.“ aus. Der zweite Aufruf beginnt erneut bei der ersten Zeile des Körpers und gibt beide Meldungen erneut aus. Es entstehen vier Ausgabezeilen.

    Die leeren runden Klammern sind dennoch wichtig: greet allein verweist auf das Funktionsobjekt. Es ruft die Funktion nicht auf, und print(greet) zeigt statt der Begrüßung eine Funktionsbeschreibung an.

  4. 4
    HerausforderungDie Wirkung eines fehlenden Aufrufs vorhersagen

    Was zeigt diese Datei an?

    def ready():
        print("Ready")
    
    ready
    print("Waiting")
    

    ---reveal---

    Sie zeigt nur „Waiting“ an. Die Definition erstellt ready, und der Name allein verweist auf diese Funktion, ohne sie auszuführen. Um auch die Meldung anzuzeigen, ändere ready zu ready(). Der Aufruf würde dann vor der letzten print-Anweisung ausgeführt und „Ready“ und „Waiting“ in getrennten Zeilen ausgeben.

  5. 5
    TippNamen und Körper verwendbar halten

    Verwende Namen wie print_receipt: kleingeschriebene, durch Unterstriche verbundene Wörter, die die Aufgabe beschreiben. Vermeide es, einen eingebauten Namen zu ersetzen. Eine Zuweisung von Text an input verdeckt die Funktion, sodass ein späteres input(...) versucht, Text aufzurufen, und fehlschlägt.

    Ein unfertiger Körper braucht eine Anweisung. Verwende ein eingerücktes pass als Platzhalter. Ein Kommentar allein ist kein Körper, und ein nicht eingerücktes pass stünde stattdessen außerhalb der Funktion.

  6. 6
    BeispielIn die aufrufende Funktion wechseln
    def line():
        print("----------")
    
    def banner():
        line()
        print("  REPORT")
        line()
    
    print("Start")
    banner()
    print("End")
    

    Zunächst werden beide Definitionen ohne Ausgabe ausgeführt. Die Anweisung auf Modulebene gibt „Start“ aus, dann wechselt banner() in den Körper von banner. Dessen erste Zeile ruft line auf, sodass banner warten muss, während die Hilfsfunktion ihre Striche ausgibt. Gehe erst zum Titel weiter, wenn die Hilfsfunktion endet.

  7. 7
    ErklärungEbene für Ebene fortsetzen

    Wenn line endet, wird der Ablauf bei der Ausgabe des Titels in banner fortgesetzt. Danach ruft banner line ein zweites Mal auf und erzeugt so die zweite gestrichelte Linie. Wenn banner endet, wird das Hauptprogramm fortgesetzt und gibt „End“ aus.

    Pythons Aufrufstapel erfasst die nicht abgeschlossenen Aufrufe und ihre Rückkehrstellen. Während die Hilfsfunktion läuft, warten banner und das Hauptprogramm. Beim Nachvollziehen auf Papier kannst du diese Rückkehrstellen markieren und die Ausgabe notieren, sobald die jeweilige print-Anweisung tatsächlich ausgeführt wird.

  8. 8
    HerausforderungEinen weiteren Aufruf einer Hilfsfunktion verfolgen

    In welcher Reihenfolge erfolgt die Ausgabe?

    def inner():
        print("I")
    
    def outer():
        print("O")
        inner()
        print("P")
    
    outer()
    print("Q")
    

    ---reveal---

    Die Zeilen lauten „O“, „I“, „P“ und „Q“. Der äußere Körper gibt zuerst etwas aus, wartet auf inner und setzt dann bei seiner nächsten print-Anweisung fort. Erst nachdem outer endet, wird die letzte Anweisung auf Modulebene ausgeführt. Die Reihenfolge der Definitionen allein bestimmt nicht die Reihenfolge der Ausgabe.

  9. 9
    HerausforderungEine Definition sicher verschieben

    Eine Datei definiert show mit einem Körper, der border aufruft. Danach definiert sie border und endet mit einer Schleife, die show() zweimal aufruft. Führt die weiter unten stehende Definition der Hilfsfunktion zu einem Fehler, und wie oft wird border ausgeführt?

    ---reveal---

    Das Programm funktioniert: Beide Definitionen wurden ausgeführt, bevor die Schleife show aufruft. Jeder Aufruf beginnt show bei der ersten Zeile seines Körpers und erreicht einen Aufruf von border, sodass die Hilfsfunktion zweimal läuft. Würde die Schleife über die Definition der Hilfsfunktion verschoben, wäre deren Name nicht verfügbar, wenn er erstmals gebraucht wird.

  10. 10
    ZusammenfassungBei der ersten aktiven Anweisung beginnen

    Wenn du ein Programm mit Funktionen nachvollziehst:

    • Prüfe Kopf und Einrückung, um jeden Körper zu finden.
    • Beginne mit den Anweisungen auf Modulebene und wechsle nur durch einen Aufruf in einen Körper.
    • Markiere die nächste Anweisung des aufrufenden Codes, bevor du einer Hilfsfunktion folgst.
    • Notiere die Ausgabe, wenn ihre print-Anweisung ausgeführt wird.

    Schlägt ein Aufruf fehl, lies den letzten Fehler des Tracebacks und untersuche dann die fehlerhafte Zeile im Körper und den Aufruf, der dorthin führte. Der Aufrufpfad ist oft der Schlüssel zum Verständnis des Fehlers.

2

Die Parameterstellen belegen

13 Schritte
Ordne Werte nach Position oder Namen zu und untersuche dann Standardwerte, die zum Zeitpunkt der Definition erstellt werden.

Speichere diese Einheit, um jede Interaktive Lektion Schritt für Schritt durchzugehen.

  1. 1
    EinführungEine Aufgabe mit verschiedenen Werten wiederverwenden
  2. 2
    BeispielDie erste und zweite Eingabe zuordnen
  3. 3
    ErklärungArgumente vor dem Körper auswerten
  4. 4
    HerausforderungDie Argumentanzahl prüfen
  5. 5
    ErklärungNamen verwenden, um die Rollen zu zeigen
  6. 6
    HerausforderungEine doppelt belegte Stelle korrigieren
  7. 7
    TippSchlüsselwortoptionen eingebauter Funktionen lesen
  8. 8
    BeispielDie häufige Wahl optional machen
  9. 9
    HerausforderungEine optionale Wahl anhand des Namens überspringen
  10. 10
    KernaussageEin Standardwert behält den Wert vom Zeitpunkt seiner Erstellung
  11. 11
    BeispielErkennen, warum eine Liste als Standardwert Elemente behält
  12. 12
    HerausforderungStandardwerte mit benannten Eingaben kombinieren
  13. 13
    ZusammenfassungDen Kopf mit dem Aufruf abgleichen
3

Werte zurück zum aufrufenden Code verfolgen

14 Schritte
Unterscheide Ausgabe und Ergebnisse und erstelle dann Zweige, Suchen und verschachtelte Aufrufe, die die benötigten Werte zurückgeben.

Speichere diese Einheit, um jede Interaktive Lektion Schritt für Schritt durchzugehen.

  1. 1
    EinführungBeobachten, was der aufrufende Code erhält
  2. 2
    BeispielDen Aufruf durch sein Ergebnis ersetzen
  3. 3
    ErklärungBildschirmausgabe und Ergebnis unterscheiden
  4. 4
    HerausforderungDen für die Addition verwendeten Wert finden
  5. 5
    TippPrüfen, wo der Aufruf ausgeführt wird
  6. 6
    BeispielBei der ersten zutreffenden Note anhalten
  7. 7
    HerausforderungDie Eingabe zwischen den Zweigen abdecken
  8. 8
    KernaussageEinen Vergleich die Frage beantworten lassen
  9. 9
    BeispielEinen gefundenen Teiler zurückgeben
  10. 10
    HerausforderungEin zu früh zurückgegebenes Erfolgsergebnis korrigieren
  11. 11
    BeispielEin zusammengefasstes Ergebnis entpacken
  12. 12
    BeispielEin inneres Ergebnis nach außen übergeben
  13. 13
    HerausforderungEinen vorzeitigen Pfad mit einem Ergebnis kombinieren
  14. 14
    ZusammenfassungPfade und Rückgabewerte gemeinsam verfolgen
4

Namen und gemeinsam referenzierte Objekte verfolgen

11 Schritte
Unterscheide lokale und globale Namen und mache dann eine veränderliche Summe im aufrufenden Code sichtbar.

Speichere diese Einheit, um jede Interaktive Lektion Schritt für Schritt durchzugehen.

  1. 1
    EinführungFragen, wohin der Name gehört
  2. 2
    BeispielJedem Aufruf einen eigenen Zähler geben
  3. 3
    ErklärungVerdeckte Namen auseinanderhalten
  4. 4
    HerausforderungDie Aktualisierung im aufrufenden Code sichtbar machen
  5. 5
    BeispielEine gemeinsam referenzierte Liste durch einen Parameter verfolgen
  6. 6
    BeispielEine globale Variable ohne Deklaration lesen
  7. 7
    KernaussageEine Zuweisung bestimmt den lokalen Gültigkeitsbereich frühzeitig
  8. 8
    HerausforderungDen Gültigkeitsbereich einer Aktualisierung wählen
  9. 9
    VerbindungDen veränderlichen Wert durch den Aufruf führen
  10. 10
    HerausforderungVeränderung eines Objekts und erneute Zuweisung unterscheiden
  11. 11
    ZusammenfassungDie Operation benennen, bevor du ihre Wirkung vorhersagst
5

Einen Bericht über Testergebnisse entwerfen und prüfen

12 Schritte
Dokumentiere eine Hilfsfunktion, plane ihre Eingaben und Ergebnisse und prüfe dann Grenzen und Daten des aufrufenden Codes, bevor du das Programm verbindest.

Speichere diese Einheit, um jede Interaktive Lektion Schritt für Schritt durchzugehen.

  1. 1
    EinführungEin Programm aus klaren Aufgaben erstellen
  2. 2
    BeispielDie Beschreibung so platzieren, dass die Hilfe sie findet
  3. 3
    ErklärungEinzelheiten ergänzen, die einen Aufruf beeinflussen
  4. 4
    HerausforderungDie fehlende Dokumentation finden
  5. 5
    ErklärungFür jede Hilfsfunktion eine Aufgabe wählen
  6. 6
    BeispielDie Hilfsfunktionen in main verbinden
  7. 7
    HerausforderungBerechnung und Anzeige trennen
  8. 8
    TippBeim Erstellen ein funktionierendes Programm behalten
  9. 9
    BeispielEine Grenze prüfen, die einen Programmfehler aufdecken kann
  10. 10
    HerausforderungFinden, wo ein falscher Datentyp hineingelangt
  11. 11
    HerausforderungDokumentation und Prüfung in Übereinstimmung halten
  12. 12
    ZusammenfassungDie Schnittstelle als Leitfaden für Prüfungen nutzen

Python-Funktionen: Übungsaufgaben

40 Übungsfragen in 4 Sets

Set 1: Aufrufe lesen und ihre Ergebnisse verfolgen10 Übungsfragen

Frage 1 von 10

Welche Ausgabe erzeugt dieses Programm?

def announce():
    print("Open")

print("Ready")
  1. „Open“ und danach „Ready“.
  2. Nur „Ready“ in einer Zeile.
  3. „Ready“ und darunter „Open“.
  4. Überhaupt keine Ausgabe.
Antwort zeigenAntwort ausblenden
Antwort: B
Das Programm gibt „Ready“ aus, weil diese Anweisung auf Modulebene ausgeführt wird. Die Definition von announce erstellt die Funktion, wechselt aber nie in ihren Körper, sodass „Open“ nicht erscheint. Das eingebaute print wird trotzdem ausgeführt, obwohl die neu definierte Funktion nie aufgerufen wird.

Frage 2 von 10

In welcher Reihenfolge erfolgt die Ausgabe?

def mark():
    print("M")

def stage():
    print("S")
    mark()
    print("T")

print("R")
stage()
  1. „M“, „S“, „T“, „R“
  2. „R“, „M“, „S“, „T“
  3. „R“, „S“, „T“, „M“
  4. „R“, „S“, „M“, „T“
Antwort zeigenAntwort ausblenden
Antwort: D
Die print-Anweisung auf Modulebene erzeugt „R“, dann gibt stage „S“ aus und ruft mark auf, das „M“ ausgibt. Nachdem dieser innere Aufruf endet, wird stage fortgesetzt und gibt „T“ aus. Wer „M“ ans Ende setzt, übersieht, dass der aufrufende Code auf seine Hilfsfunktion wartet, bevor er fortfährt.

Frage 3 von 10

Was gibt dieser Aufruf aus?

def describe_trip(origin, destination):
    print(origin, "to", destination)

describe_trip("Mesa", "Salem")
  1. „Mesa to Salem“
  2. „Salem to Mesa“
  3. „origin to destination“
  4. „Mesa Salem to“
Antwort zeigenAntwort ausblenden
Antwort: A
Das erste Positionsargument belegt origin und das zweite destination, sodass der Körper „Mesa to Salem“ ausgibt. Um die Namen umzukehren, müssten die Argumente oder die Rollen der Parameter im Körper vertauscht werden. Python ordnet Positionen zu, ohne die Bedeutung der Stadtnamen zu deuten.

Frage 4 von 10

Wie kannst du diese Funktion mit „Inez“ für die Person und „West“ für den Raum aufrufen?

def show_booking(person, room):
    print(person, room)
  1. show_booking(person="Inez", "West")
  2. show_booking("Inez", person="West")
  3. show_booking(room="West", person="Inez")
  4. show_booking(name="Inez", room="West")
Antwort zeigenAntwort ausblenden
Antwort: C
Durch die Nennung von room und person werden beide Parameter auch in umgekehrter Reihenfolge richtig belegt. Ein Positionswert nach person="Inez" ist ein Syntaxfehler, daher machen die beabsichtigten Werte allein diesen Aufruf nicht gültig. Schlüsselwörter müssen außerdem exakt die Namen aus dem Kopf verwenden und dürfen einen Parameter nicht zweimal belegen.

Frage 5 von 10

Was wird angezeigt?

def label(text, copies=2):
    print(text * copies)

label("Go")
  1. „Go“
  2. „GoGo“
  3. „Go2“
  4. „Go Go“
Antwort zeigenAntwort ausblenden
Antwort: B
Der Aufruf liefert text und lässt copies aus, sodass copies seinen Standardwert 2 erhält. Die Multiplikation von „Go“ mit 2 wiederholt den Text als „GoGo“, ohne ein Leerzeichen einzufügen. Eine Ausgabe von nur „Go“ würde das bei diesem Aufruf verwendete Standardargument ignorieren.

Frage 6 von 10

Was gibt die letzte Zeile aus?

def triple(value):
    print(value * 3)

answer = triple(4)
print(answer)
  1. „None“
  2. „12“
  3. „4“
  4. Nichts; die letzte Zeile wird übersprungen.
Antwort zeigenAntwort ausblenden
Antwort: A
Die Hilfsfunktion gibt „12“ aus, erreicht dann das Ende ihres Körpers und gibt None zurück. Die Zuweisung speichert diesen Rückgabewert in answer, sodass die letzte Zeile „None“ ausgibt. Die angezeigte 12 ist eine Wirkung der inneren print-Anweisung und nicht automatisch der Rückgabewert der Hilfsfunktion.

Frage 7 von 10

Was gibt diese Funktion für first_factor(25) zurück?

def first_factor(n):
    for candidate in range(2, n):
        if n % candidate == 0:
            return candidate
        return n
  1. 5 nach der Prüfung der Kandidaten 2 bis 5.
  2. None, weil der erste Kandidat scheitert.
  3. 25 nach der Prüfung aller Kandidaten.
  4. 25 nach der Prüfung nur des Kandidaten 2.
Antwort zeigenAntwort ausblenden
Antwort: D
Der Kandidat 2 teilt 25 nicht, daher erreicht der Ablauf bereits im ersten Schleifendurchlauf return n und gibt 25 zurück. Die Funktion prüft den Kandidaten 5 nie. Ein return nach der gesamten Schleife würde die Suche fortsetzen lassen, aber die Einrückung setzt diese Ersatzrückgabe hier innerhalb der Schleife.

Frage 8 von 10

Wie lauten die beiden Ausgabezeilen?

level = 7

def show_level():
    level = 3
    print(level)

show_level()
print(level)
  1. „3“, dann „3“
  2. „7“, dann „3“
  3. „3“, dann „7“
  4. „7“, dann „7“
Antwort zeigenAntwort ausblenden
Antwort: C
Die Zuweisung innerhalb von show_level erstellt ein lokales level, sodass die Hilfsfunktion „3“ ausgibt. Sie lässt den globalen Wert bei 7, den die letzte print-Anweisung anzeigt. Wer zweimal 3 erwartet, behandelt eine lokale Zuweisung so, als würde sie der gleich geschriebenen globalen Variable einen neuen Wert zuweisen.

Frage 9 von 10

Welche Rolle hat die erste Zeichenkette in dieser Funktion?

def square(n):
    """Return the square of n."""
    return n * n
  1. Eine gespeicherte Beschreibung, die help(square) anzeigt.
  2. Der Text, den jeder Aufruf von square zurückgibt.
  3. Eine Meldung, die vor der Multiplikation ausgegeben wird.
  4. Ein Standardwert, der beim Weglassen von n gilt.
Antwort zeigenAntwort ausblenden
Antwort: A
Weil die Zeichenkette die erste Anweisung im Körper ist, wird sie zum Docstring der Funktion und in square.__doc__ gespeichert. Ein Aufruf von square gibt weiterhin den numerischen Ausdruck n * n zurück. Ein Docstring beschreibt die Funktion; er ist weder eine automatische Ausgabe noch ihre return-Anweisung.

Frage 10 von 10

Ein Programm liest eine Entfernung ein, rechnet sie um und zeigt eine Meldung an. Mit welcher Schnittstelle lässt sich die Umrechnung prüfen, ohne eine Eingabe einzutippen?
  1. Eine Umrechnungsfunktion ohne Parameter, die die Entfernung einliest.
  2. Eine Umrechnungsfunktion, die die Entfernung entgegennimmt und den umgerechneten Wert zurückgibt.
  3. Eine Umrechnungsfunktion, die die Entfernung entgegennimmt und den umgerechneten Wert ausgibt.
  4. Eine Umrechnungsfunktion ohne Parameter, die eine globale Entfernung ändert.
Antwort zeigenAntwort ausblenden
Antwort: B
Eine Hilfsfunktion mit einem Entfernungsparameter und einer zurückgegebenen Zahl lässt sich direkt mit einer bekannten Eingabe aufrufen und mit einem erwarteten Ergebnis vergleichen. Eine Hilfsfunktion, die nur ausgibt, zeigt die Antwort an, liefert dem aufrufenden Code aber None. Bleiben Eingabe und Anzeige im aufrufenden Code, lässt sich die Berechnung leichter wiederverwenden und prüfen.
Set 2: Eingaben, Gültigkeitsbereiche und fehlende Ergebnisse verfolgen10 Übungsfragen

Speichere diese Einheit, um jede Antwort zu sehen und jedes Set zu üben.

Frage 1 von 10

Wie sollte dieser unfertige Funktionskörper ergänzt werden, damit die Datei gültig ist, die Funktion aber noch nichts tut?

def print_ticket():
    # Work to be added later
  1. Füge unter dem Kommentar ein nicht eingerücktes pass hinzu.
  2. Füge darunter einen weiteren eingerückten Kommentar hinzu.
  3. Füge unter dem Kommentar ein eingerücktes pass hinzu.
  4. Füge darunter ein nicht eingerücktes print_ticket() hinzu.
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 2 von 10

Was gibt dieses Programm aus?

def show_scaled(value, factor):
    print(value * factor)

entry = "6"
show_scaled(entry, 3)
  1. „666“
  2. „18“
  3. „6 6 6“
  4. „9“
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 3 von 10

Welcher Wert wird zurückgegeben?

step = 4

def advance(position, amount=step):
    return position + amount

step = 9
result = advance(10)
  1. 19
  2. 9
  3. 10
  4. 14
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 4 von 10

Welche einzelne Änderung sorgt dafür, dass result den Wert 16 enthält, ohne ihn innerhalb der Hilfsfunktion anzuzeigen?

def square(n):
    print(n * n)

result = square(4)
  1. Ersetze den Körper durch return print(n * n).
  2. Ersetze den Körper durch return n * n.
  3. Füge nach der vorhandenen print-Anweisung return hinzu.
  4. Ersetze den Aufruf durch result = print(square(4)).
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 5 von 10

Was wird ausgegeben?

def pack(total, size):
    return total // size, total % size

def double(n):
    return n * 2

boxes, spare = pack(29, 6)
print(double(boxes) + spare)
  1. „12“
  2. „9“
  3. „14“
  4. „13“
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 6 von 10

Was wird nach beiden Aufrufen ausgegeben?

def add_guest(guests):
    guests.append("Sol")

def replace_guests(guests):
    guests = ["Tao"]

party = ["Ren"]
add_guest(party)
replace_guests(party)
print(party)
  1. ['Tao']
  2. ['Ren']
  3. ['Ren', 'Sol']
  4. ['Ren', 'Sol', 'Tao']
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 7 von 10

Was geschieht beim Aufruf von inspect()?

count = 11

def inspect():
    print(count)
    count = 2

inspect()
  1. Der Aufruf löst UnboundLocalError aus, bevor ein Wert ausgegeben wird.
  2. Er gibt „11“ aus und ändert dann das globale count auf 2.
  3. Er gibt „11“ aus und erstellt dann das lokale count mit 2.
  4. Er gibt „2“ aus, weil die lokale Zuweisung zuerst ausgeführt wird.
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 8 von 10

Was enthält show.__doc__?

def show():
    value = 2
    """Display the current value."""
    print(value)
  1. Den Satz „Display the current value.“
  2. None
  3. Die Zahl 2
  4. Die Quelltextzeile print(value)
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 9 von 10

Drei Teile eines Programms geben einen Titel zwischen identischen Trennlinien aus. Welche Änderung beseitigt wiederholte Logik und erhält unterschiedliche Titel?
  1. Erstelle für jeden Titel eine eigene Funktion ohne Parameter.
  2. Speichere jeden Titel global und lies ihn mit einer Ausgabefunktion.
  3. Setze alle drei Blöcke unverändert in main.
  4. Schreibe print_heading(title) und übergib jeden Titel.
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 10 von 10

Eine Kategorie soll ab 50 „voll“ und unter 50 „teilweise“ sein. Welches Paar von Testeingaben deckt einen versehentlichen Test > 50 am besten auf?
  1. 50 und 49
  2. 51 und 52
  3. 25 und 30
  4. 49 und 48
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Set 3: Aufrufe untersuchen und Programmverhalten korrigieren10 Übungsfragen

Speichere diese Einheit, um jede Antwort zu sehen und jedes Set zu üben.

Frage 1 von 10

Warum funktioniert dieses Programm, obwohl tick unter report definiert ist?

def report():
    tick()

def tick():
    print("Done")

report()
  1. Python führt jeden Funktionskörper vor allen Aufrufen einmal aus.
  2. Die Definition von report verschiebt tick über sich selbst.
  3. Der Körper von report wird in die Definition von tick kopiert.
  4. Beide Definitionen laufen, bevor report() die Funktion tick aufruft.
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 2 von 10

Welcher Argumentwert gelangt zu width?

def show_width(width):
    print(width)

base = 8
show_width(base + 3)
  1. 8
  2. 11
  3. Der Text „base + 3“
  4. Kein Wert, weil die Namen verschieden sind.
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 3 von 10

Warum schlägt dieser Aufruf fehl?

def mark_pages(first, last):
    print(first, last)

mark_pages(4, first=9)
  1. Das Schlüsselwort folgt auf ein Positionsargument.
  2. Zwei ganzzahlige Argumente dürfen nicht zusammen verwendet werden.
  3. first erhält zwei Werte und last erhält keinen.
  4. Schlüsselwortnamen müssen Variablennamen des aufrufenden Codes entsprechen.
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 4 von 10

Wie lauten die beiden ausgegebenen Listen?

def collect(value, bucket=[]):
    bucket.append(value)
    return bucket

print(collect("red"))
print(collect("blue", []))
  1. ['red'], dann ['blue']
  2. ['red'], dann ['red', 'blue']
  3. ['red', 'blue'], dann ['blue']
  4. ['blue'], dann ['red', 'blue']
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 5 von 10

Wie lautet die vollständige Ausgabe?

def shift(n):
    return n + 2
    print("shifted")

shift(5)
print("done")
  1. „shifted“, dann „done“
  2. „7“, dann „done“
  3. Nur „done“
  4. Nur „shifted“
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 6 von 10

Eine Funktion muss genau dann True zurückgeben, wenn eine ganze Zahl eine Primzahl ist. Warum akzeptiert dieser Körper 35 fälschlich?

def is_prime(n):
    if n < 2:
        return False
    for d in range(2, n):
        if n % d == 0:
            return False
        else:
            return True
  1. Er probiert alle Kandidaten, überspringt aber 5.
  2. Er gibt beim Kandidaten 5 False zurück.
  3. Er behandelt jede ungerade Zahl unter 2 als Primzahl.
  4. Er gibt beim Kandidaten 2 True zurück, bevor er 5 prüft.
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 7 von 10

Was wird ausgegeben?

total = 2

def add(amount):
    global total
    total = total + amount
    return total

first = add(4)
second = add(first)
print(total, second)
  1. „6 12“
  2. „12 12“
  3. „8 8“
  4. „6 6“
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 8 von 10

Eine Funktion ändert ihre Standarddauer von 15 Minuten auf 20 Minuten, bei gleicher Berechnung und gleichen Einheiten. Welche Änderung der Dokumentation ist nötig?
  1. Aktualisiere den dokumentierten Standardwert des optionalen Parameters auf 20 Minuten.
  2. Benenne die Funktion im Docstring um, um 20 Minuten zu erwähnen.
  3. Verschiebe den Docstring hinter die Berechnung, um ihr neues Ergebnis zu dokumentieren.
  4. Entferne die Parameterbeschreibung, weil der Kopf seinen Namen zeigt.
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 9 von 10

Eine numerische Hilfsfunktion behält nach der Vereinfachung ihres Körpers denselben Namen, dieselben Parameter, Rückgabewerte und dokumentierten Wirkungen. Warum kann vorhandener aufrufender Code unverändert bleiben?
  1. Der aufrufende Code erhält alle lokalen Variablen aus dem neuen Körper.
  2. Python speichert den alten Körper, bis alle Aufrufe umgeschrieben sind.
  3. Der aufrufende Code nutzt eine Schnittstelle, deren Verhalten erhalten bleibt.
  4. Ein Docstring lässt Python jeden Aufruf automatisch korrigieren.
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 10 von 10

Eine numerische Hilfsfunktion schlägt bei if score >= 60: fehl, nachdem der aufrufende Code input("Score: ") übergeben hat. Welche Korrektur behebt das Problem mit dem Eingabetyp?
  1. Ändere den Vergleich zu score >= "60".
  2. Wandle die Eingabe mit float() um, bevor du die Hilfsfunktion aufrufst.
  3. Füge nach dem Vergleich eine print-Anweisung zur Anzeige von score hinzu.
  4. Entferne den Parameter und lies stattdessen ein globales score.
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Set 4: Funktionsregeln in neuen Situationen kombinieren10 Übungsfragen

Speichere diese Einheit, um jede Antwort zu sehen und jedes Set zu üben.

Frage 1 von 10

Wie sollte eine Funktion, die einen Zahlungsbeleg anzeigt, im üblichen Python-Stil heißen?
  1. print_receipt
  2. print-receipt
  3. 2print_receipt
  4. print receipt
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 2 von 10

Was wird ausgegeben?

def outer():
    inner()
    print("Y")

outer()

def inner():
    print("X")
  1. „X“, dann „Y“
  2. Nur „Y“, gefolgt von einem NameError
  3. Keine Ausgabe; NameError tritt in outer auf.
  4. Nur „X“, gefolgt von einem NameError
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 3 von 10

Wie lautet die vollständige Ausgabe einschließlich der Zeilenumbrüche?

print("N", "S", sep="/", end="|")
print("E", "W", sep="-")
  1. Zwei Zeilen: „N/S|“ und dann „E-W“
  2. Eine Zeile: „N/S|E-W“
  3. Eine Zeile: „N S|E W“
  4. Zwei Zeilen: „N/S“ und dann „|E-W“
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 4 von 10

Ein neuer Aufruf, der items auslässt, soll mit einer neuen Liste beginnen, eine übergebene Liste aber direkt erweitern. Welcher Ersatzkörper ist richtig?

def add_code(code, items=None):
    # replacement body
  1.     items = []
        items.append(code)
        return items
    
  2.     if items == []:
            items = []
        items.append(code)
        return items
    
  3.     if items is None:
            return []
        items.append(code)
        return items
    
  4.     if items is None:
            items = []
        items.append(code)
        return items
    
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 5 von 10

Welche Änderung lässt diese Funktion den ersten passenden Kandidaten oder erst nach dem Scheitern aller Kandidaten None zurückgeben?

def find_divisor(n):
    for d in range(3, n):
        if n % d == 0:
            return d
        else:
            return None
  1. Ändere return None im else zu return False.
  2. Entferne das else und setze return None hinter die Schleife.
  3. Setze beide return-Anweisungen hinter die Schleife.
  4. Verschiebe return d innerhalb der Schleife vor den if-Test.
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 6 von 10

Was gibt die letzte Zeile aus?

def change(values):
    values.append("B")
    values = ["C"]
    values.append("D")
    return values

original = ["A"]
result = change(original)
print(original, result)
  1. ['A'] ['C', 'D']
  2. ['A', 'B', 'D'] ['C']
  3. ['C', 'D'] ['C', 'D']
  4. ['A', 'B'] ['C', 'D']
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 7 von 10

Wie kann der aufrufende Code stock ausdrücklich aktualisieren, ohne dass die Hilfsfunktion eine globale Variable ändert?

stock = 18

def remove(stock, amount):
    return stock - amount

# caller statement
  1. remove(stock, 4)
  2. stock = remove(4, stock)
  3. stock = remove(stock, 4)
  4. remove(stock=4, amount=stock)
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 8 von 10

Eine Hilfsfunktion als Platzhalter enthält nur einen Docstring und pass. Ihr aufrufender Code addiert das Ergebnis der Hilfsfunktion zu 7 und erhält einen TypeError. Was sollte als Nächstes implementiert werden?
  1. Gib das numerische Ergebnis zurück, das die Aufgabe der Hilfsfunktion verspricht.
  2. Gib die versprochene Zahl vor der pass-Anweisung aus.
  3. Verschiebe den Docstring unter pass, um ihn ausführbar zu machen.
  4. Wiederhole den Aufruf der Hilfsfunktion, bevor du ihr Ergebnis zu 7 addierst.
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 9 von 10

Was wird ausgegeben?

def add_fee(amount):
    return amount + 3

def twice(amount):
    return amount * 2

print(twice(add_fee(5)))
  1. „13“
  2. „8“
  3. „10“
  4. „16“
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 10 von 10

Was wird ausgegeben?

rate = 2

def scale(value, factor=rate):
    return value * factor

def reset():
    global rate
    rate = 5

reset()
print(scale(3), scale(3, rate))
  1. „15 15“
  2. „6 6“
  3. „6 15“
  4. „15 6“
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Hängst du bei deiner eigenen Aufgabe fest? Hausaufgabenhilfe

Schlüsselbegriffe

56 Schlüsselbegriffe, jeweils mit Definition

A

Argument
Ein Argument ist ein Wert, der in einem Funktionsaufruf übergeben wird, nachdem ein Ausdruck, der diesen Wert erzeugt, gegebenenfalls ausgewertet wurde.
In area(side + 1, 2) berechnet Python das erste Argument, bevor es den Flächenkörper beginnt.
aufrufender Code
Aufrufender Code ruft eine Funktion auf und wartet auf ihr Ende, bevor er nach dem Aufruf fortfährt.
Wenn banner() die Funktion line() aufruft, ist der Körper von banner der aufrufende Code der Funktion zum Zeichnen der Linie.
Aufrufstapel
Der Aufrufstapel ist Pythons Aufzeichnung von Aufrufen, die begonnen haben, aber noch nicht beendet sind, einschließlich der Stellen, an denen ihr aufrufender Code fortgesetzt wird.
Während eine Hilfsfunktion für eine Linie innerhalb eines Banneraufrufs läuft, haben beide nicht abgeschlossenen Aufrufe Plätze im Aufrufstapel.

B

boolesche Funktion
Eine boolesche Funktion beantwortet eine Ja-Nein-Frage durch Rückgabe von True oder False, oft direkt aus einem Vergleich.
Der Körper return n % 2 == 0 ermöglicht es, is_even(n) direkt als if-Bedingung zu verwenden.

D

Debug-Ausgabe
Eine Debug-Ausgabe ist die vorübergehende Anzeige eines Werts bei der Untersuchung eines Programmfehlers; sie wird nach Abschluss der Untersuchung entfernt.
Eine print-Anweisung in der ersten Zeile kann das unerwartete Testergebnis sichtbar machen, das vom aufrufenden Code bei einer Hilfsfunktion ankommt.
Docstring
Ein Docstring ist die Zeichenkette als erste Anweisung eines Funktionskörpers, die zusammen mit der Funktion gespeichert wird, um dem aufrufenden Code ihre Verwendung zu beschreiben.
Der Docstring einer Umrechnungsfunktion kann die Temperatureinheiten ihrer Ein- und Ausgabe erklären, bevor jemand die Formel liest.

E

einzeiliger Docstring
Ein einzeiliger Docstring ist ein kurzer Aufforderungssatz, der üblicherweise in dreifachen doppelten Anführungszeichen steht und mit einem Punkt endet.
„Gib die Fläche eines Rechtecks zurück.“ beschreibt die Aufgabe, ohne die Signatur der Funktion zu wiederholen.
end
Der Parameter end von print steuert den Text, der nach den angezeigten Werten angehängt wird; standardmäßig ist das ein Zeilenumbruch.
Mit end="..." kann die nächste print-Anweisung nach den Punkten fortsetzen, statt eine neue Zeile zu beginnen.
Entpacken
Das Entpacken weist die einzelnen Werte eines zusammengefassten Ergebnisses passenden Namen zu und behält ihre ursprüngliche Reihenfolge bei.
Wenn share(17, 5) die Werte 17 // 5, 17 % 5 zurückgibt, setzt die Zuweisung each, left = share(17, 5) die 3 in each und die 2 in left ein.
erforderlicher Parameter
Ein erforderlicher Parameter hat keinen Standardwert und muss in jedem gültigen Aufruf einen Wert erhalten, nach Position oder durch ein akzeptiertes Schlüsselwort.
Bei def greet(name, greeting="Hello"): verursacht das Weglassen von name einen Fehler wegen eines fehlenden Arguments.
erneute Zuweisung
Eine erneute Zuweisung gibt einem vorhandenen Namen einen neuen Wert oder ein neues Objekt; die erneute Zuweisung an einen Parameter ändert diese lokale Bindung.
Die Zeile points = points + 10 ändert den lokalen Parameter und lässt die Punktzahl des aufrufenden Codes unverändert.
erwartetes Ergebnis
Ein erwartetes Ergebnis ist eine vor einer Prüfung unabhängig ermittelte Antwort, mit der beurteilt wird, was eine Funktion tatsächlich zurückgibt.
Wenn du ein arithmetisches Mittel von Hand berechnest, kannst du eine plausibel aussehende, aber falsche Programmausgabe erkennen.

F

Funktion
Eine Funktion ist ein benannter Codeblock, der bei einem Aufruf eine Aufgabe ausführt und einem Programm ermöglicht, dieselbe Logik wiederzuverwenden.
Ein Belegprogramm kann print_receipt() aufrufen, wann immer es einen weiteren Beleg anzeigen muss.
Funktion mit nutzbarem Rückgabewert
Eine Funktion mit nutzbarem Rückgabewert gibt ein nützliches Ergebnis zurück, das der aufrufende Code in einem Ausdruck, einer Zuweisung oder einer Bedingung verwenden kann.
Eine Temperaturumrechnung, die eine Zahl zurückgibt, kann eine ausgegebene Tabelle oder einen Vergleich mit einem Grenzwert speisen.
Funktion ohne nutzbaren Rückgabewert
Eine Funktion ohne nutzbaren Rückgabewert wird wegen einer Wirkung wie einer Ausgabe verwendet und liefert über None hinaus kein nutzbares Ergebnis.
Eine Funktion zur Ausgabe einer Begrüßung kann erfolgreich „Hello!“ anzeigen, obwohl ihr aufrufender Code None erhält.
Funktionsaufruf
Ein Funktionsaufruf ist ein Ausdruck, der eine Funktion ausführt. Er wird mit ihrem Namen und runden Klammern geschrieben, die gegebenenfalls Argumente enthalten.
Die Zeile greet() führt die Begrüßung aus, eine Zeile mit nur greet dagegen nicht.
Funktionsdefinition
Eine Funktionsdefinition ist eine def-Anweisung mit einem Kopf und einem eingerückten Körper, die eine Funktion unter einem Namen erstellt.
Python erstellt greet bei def greet(): und wartet auf einen Aufruf, bevor es den Körper ausführt.
Funktionskopf
Ein Funktionskopf ist die einleitende Zeile mit def, dem Funktionsnamen, runden Klammern für die Parameter und einem Doppelpunkt.
In def print_line(length): benennt der Kopf die Aufgabe und ihre Eingabe, bevor der Körper beginnt.
Funktionskörper
Ein Funktionskörper ist der eingerückte Anweisungsblock unter dem Funktionskopf, der bei jedem Aufruf von Anfang an durchlaufen wird.
Zwei eingerückte print-Zeilen unter def greet(): gehören beide zum Körper der Funktion.
Funktionsplatzhalter
Ein Funktionsplatzhalter ist eine unfertige Funktion mit ihrem vorgesehenen Kopf und einem Platzhalterkörper, sodass aufrufender Code während der Entwicklung laufen kann.
Ein Docstring und pass bilden einen gültigen Funktionsplatzhalter, dessen Aufrufe bis zur Implementierung allerdings weiterhin None zurückgeben.

G

gemischte Argumentübergabe
Bei der gemischten Argumentübergabe werden einige Werte nach Position und andere per Schlüsselwort übergeben, wobei die Positionswerte zuerst stehen.
In describe_pet("cat", name="Milo") wird die erste Stelle nach Position und die zweite nach Namen belegt.
global-Anweisung
Die global-Anweisung lässt einen Namen innerhalb einer Funktion bei nachfolgenden Lesezugriffen und Zuweisungen auf die Bindung auf Dateiebene verweisen.
Setze global total vor die Verwendung von total in der Funktion, um einen gemeinsam genutzten laufenden Zähler zu aktualisieren.
globale Variable
Eine globale Variable gehört zum globalen Gültigkeitsbereich einer Datei und kann nach den Regeln der Namenssuche von Funktionen in dieser Datei gelesen werden.
Ein x = 10 auf Modulebene bleibt 10, wenn eine Hilfsfunktion ihr eigenes separates lokales x = 5 setzt.
Grenzwerttest
Ein Grenzwerttest prüft eine Eingabe genau an einer Entscheidungsgrenze, oft zusammen mit einem nahen Wert, der den anderen Pfad nimmt.
Die Ergebnisse 90 und 89,9 decken eine Notenbedingung auf, die versehentlich > statt >= verwendet.
Gültigkeitsbereich
Der Gültigkeitsbereich ist der Teil eines Programms, in dem ein Name verwendet werden kann; er bestimmt, welche Variable ein Namensverweis bezeichnet.
Ein nur innerhalb von make_greeting() erstellter Name ist für eine print-Anweisung auf Modulebene nach dem Aufruf nicht verfügbar.

H

help
Die Funktion help zeigt Informationen über eine Funktion an, darunter ihre Signatur und ihren gespeicherten Docstring, sofern vorhanden.
Verwende help(to_fahrenheit), um die Umrechnungsfunktion zu untersuchen, ohne ihr zuerst eine Temperatur zu übergeben.

I

inkrementelle Entwicklung
Die inkrementelle Entwicklung erstellt ein Programm durch kleine Ergänzungen und prüft jeden Teil, bevor weitere Arbeit verbunden wird.
Die vorherige Prüfung einer Hilfsfunktion für das arithmetische Mittel begrenzt den zu untersuchenden Code, wenn ein späterer Notenbericht fehlschlägt.

K

Konstante
Eine Konstante ist eine Einstellung, die fest bleiben soll; nach Python-Konvention werden Konstantennamen auf Dateiebene großgeschrieben.
Eine Funktion kann TAX_RATE = 0.25 lesen, um eine Steuer zu berechnen, ohne den Namen als global zu deklarieren.

L

lokale Variable
Eine lokale Variable gehört zu einem Funktionsaufruf; dazu zählen Parameter und gewöhnliche Namen, denen in dieser Funktion Werte zugewiesen werden.
Jeder Aufruf kann sein eigenes count = 0 initialisieren, sodass zwei Aufrufe unabhängig voneinander den Wert 1 ausgeben können.

M

main
Eine main-Funktion koordiniert die kleineren Aufgaben eines Programms und verbindet Eingaben, Ergebnisse der Hilfsfunktionen und die abschließende Anzeige.
Ein abschließender Aufruf main() führt die Schritte eines Berichts über Testergebnisse aus, nachdem alle Definitionen der Hilfsfunktionen ausgeführt wurden.
mehrzeiliger Docstring
Ein mehrzeiliger Docstring enthält eine Zusammenfassung, eine Leerzeile und weitere Einzelheiten zu Eingaben, Standardwerten, Ergebnissen und Wirkungen.
Eine Funktion zum Aufteilen einer Rechnung kann dokumentieren, dass tip_rate=0.2 einen Anteil der Rechnung bedeutet und nicht 20.

N

None
None ist Pythons spezieller Wert für „kein Wert“ und auch als Signal nützlich, dass eine optionale Eingabe ausgelassen wurde.
Bei basket=None kann die Funktion innerhalb von if basket is None: eine neue Liste erstellen.

O

optionaler Parameter
Ein optionaler Parameter hat einen Standardwert, sodass ein Aufruf das Argument auslassen oder den Standardwert durch ein ausdrückliches Argument ersetzen kann.
Der Aufruf einer Kaffeefunktion kann milk="oat" setzen und einen früheren optionalen Parameter für die Anzahl der Espressos bei seinem Standardwert belassen.

P

Parameter
Ein Parameter ist ein Name in einem Funktionskopf, der für einen Aufruf einen Argumentwert als lokale Variable erhält.
Der Kopf def area(width, height): gibt jedem Flächenaufruf lokale Namen für seine beiden Abmessungen.
pass
Die pass-Anweisung ist ein Platzhalter, der keine Aktion ausführt und einen geplanten Funktionskörper zu gültigem Python macht.
Eine Funktion, die nur pass enthält, kann aufgerufen werden, während ihr eigentliches Ausgabeverhalten noch geschrieben wird.
Positionsargument
Ein Positionsargument wird einem Parameter anhand seiner Reihenfolge in einem Aufruf zugeordnet, wobei der erste Wert die erste Stelle belegt.
Bei describe_pet(animal, name) setzt describe_pet("cat", "Milo") den Wert „cat“ in animal ein.
Programmablauf
Der Programmablauf ist die Reihenfolge, in der Anweisungen ausgeführt werden, einschließlich der Sprünge in Funktionen und der Rückkehr zum aufrufenden Code.
Ein Bericht kann „Start“ ausgeben, in banner() wechseln, dessen Hilfsaufrufe abschließen und dann „End“ ausgeben.
prozedurale Abstraktion
Die prozedurale Abstraktion ermöglicht es Code, eine Funktion anhand ihrer vereinbarten Aufgabe zu verwenden, ohne davon abzuhängen, wie ihr Körper diese Aufgabe erfüllt.
Der aufrufende Code kann letter_grade(avg) verwenden, ohne jeden Schwellenwertvergleich im Körper zu verfolgen.

R

return-Anweisung
Eine return-Anweisung beendet den aktuellen Funktionsaufruf und sendet sein Ergebnis an den aufrufenden Code; ohne Ausdruck sendet sie None.
Die Anweisung return width * height ermöglicht es dem aufrufenden Code, eine Fläche zu speichern oder in einer weiteren Berechnung zu verwenden.
Rückgabepfad
Ein Rückgabepfad ist ein Weg durch die Zweige und Schleifen einer Funktion, der eine return-Anweisung oder das Ende des Körpers erreicht.
Eine Vorzeichenfunktion braucht ein Ergebnis für null sowie Wege, die Bezeichnungen für positive und negative Werte zurückgeben.
Rückgabewert
Ein Rückgabewert ist das Ergebnis, das ein Aufruf dem aufrufenden Code liefert und das dort gespeichert, geprüft oder an eine andere Operation übergeben werden kann.
Nach area = rectangle_area(4, 2.5) enthält area das zurückgegebene Ergebnis 10,0 zur späteren Verwendung.

S

Schlüsselwortargument
Ein Schlüsselwortargument nennt im Aufruf den Zielparameter, sodass die Zuordnung vom Namen statt von der Position abhängt.
Der Aufruf describe_pet(name="Milo", animal="cat") belegt die Parameter in einer gut lesbaren Reihenfolge.
Schnittstelle
Die Schnittstelle einer Funktion umfasst ihren Namen, ihre Parameter, ihr Rückgabeergebnis und ihr dokumentiertes Verhalten: die Vereinbarung für ihren aufrufenden Code.
Eine Berechnung kann umgeschrieben werden, während Aufrufe unverändert bleiben, wenn die Schnittstelle weiterhin dasselbe versprochene Ergebnis liefert.
sep
Der Parameter sep von print steuert den Text, der zwischen angezeigten Werten eingefügt wird; standardmäßig ist das ein Leerzeichen.
Der Aufruf print("a", "b", "c", sep="-") zeigt die drei Buchstaben als „a-b-c“ an.
Standardwert
Ein Standardwert ist ein Wert, der bei der Ausführung der Definition für einen Parameter gespeichert und verwendet wird, wenn ein Aufruf das zugehörige Argument auslässt.
In def greet(name, greeting="Hello"): kann ein Aufruf die Begrüßung auslassen und trotzdem den Namen übergeben.

T

Traceback
Ein Traceback ist ein Fehlerbericht, der den nicht abgeschlossenen Aufrufpfad, die fehlerhafte Zeile sowie den abschließenden Fehlertyp und die Meldung zeigt.
Lies in einem Traceback zuerst den letzten Fehler und untersuche dann die fehlerhafte Zeile der Hilfsfunktion und den Aufruf, der ihre Eingaben lieferte.
Tupel
Ein Tupel ist eine zusammengefasste Sequenz von Werten; durch Kommas getrennte Werte in einer Rückgabe bilden ein Tupel als Ergebnis für den aufrufenden Code.
Die Anweisung return total // people, total % people fasst einen Anteil und einen Rest zusammen.
TypeError
Ein TypeError meldet eine ungeeignete Operation auf einem Wert oder einen Aufruf mit einer ungültigen Argumentkombination.
Der Aufruf einer Funktion mit zwei Parametern und nur einem Argument löst wegen der fehlenden Eingabe einen TypeError aus.

U

UnboundLocalError
Ein UnboundLocalError tritt auf, wenn eine Funktion versucht, einen lokalen Namen zu lesen, bevor dieser lokale Name einen Wert hat.
Eine spätere Zuweisung an count macht auch ein früheres print(count) lokal, selbst wenn eine globale Variable existiert.

V

veränderlicher Standardwert
Ein veränderlicher Standardwert ist ein gespeichertes Standardobjekt, dessen Inhalt sich ändern kann, sodass Aufrufe ohne das Argument frühere Änderungen gemeinsam nutzen können.
Wird ein Element an eine Standardliste für einen Korb angehängt, kann es beim nächsten Aufruf noch sichtbar sein.
Veränderung eines Objekts
Eine Veränderung eines Objekts ändert den Inhalt eines vorhandenen Objekts, sodass ein anderer Name, der auf dasselbe Objekt verweist, die Änderung erkennen kann.
Das Anhängen von „Ben“ über einen Listenparameter ändert die Gästeliste, die der aufrufende Code übergeben hat.
verborgener Zustand
Verborgener Zustand sind Informationen, von denen eine Funktion abhängt oder die sie ändert, ohne sie über ihre Parameter und ihr Rückgabeergebnis zu zeigen.
Eine Funktion, die eine globale Summe aktualisiert, benötigt diese Summe vor einer unabhängigen Prüfung in einem vorbereiteten Zustand.
Verdeckung
Verdeckung liegt vor, wenn ein lokaler Name innerhalb einer Funktion einen gleich geschriebenen globalen Namen verbirgt, ohne die globale Bindung zu ersetzen.
Weist eine Hilfsfunktion lokal x = 5 zu, während global x = 10 gilt, ergibt das x der Hilfsfunktion 5 und ein späteres globales x weiterhin 10.
verschachtelter Aufruf
Ein verschachtelter Aufruf ist ein Funktionsaufruf innerhalb des Argumentausdrucks eines anderen Aufrufs, dessen Ergebnis benötigt wird, bevor der äußere Aufruf ausgeführt wird.
In print(to_fahrenheit(add(10, 15))) läuft die Addition vor der Umrechnung und dann die Ausgabe.
vorzeitige Rückgabe
Eine vorzeitige Rückgabe beendet eine Funktion, bevor ihre späteren Anweisungen ausgeführt werden, oft weil ein Zweig oder eine Suche die Antwort bereits gefunden hat.
Eine Teilersuche gibt für 91 die Zahl 7 zurück, sobald dieser Kandidat sie ohne Rest teilt, und beendet dabei auch die Schleife.

Z

Zerlegung
Die Zerlegung teilt ein Problem in kleinere Aufgaben auf, die jeweils als Funktion implementiert, verstanden und geprüft werden können.
Ein Programm für einen Bericht über Testergebnisse trennt das Einlesen der Ergebnisse, die Berechnung eines arithmetischen Mittels und die Wahl einer Note.

Über diese Einheit

Von StudeliFehler melden

Erstelle deine eigenen Lernmaterialien

Mach aus deinen Notizen, Folien und Dokumenten Lernleitfäden, Übungsfragen, Karteikarten und 6 weitere Tools.

Jetzt starten