Python-Funktionen
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
- 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 aufrufenSchreibe 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 nachvollziehenVerfolge die Reihenfolge, in der Python Anweisungen ausführt, wenn Funktionen andere Funktionen aufrufen, und sage daraus die Ausgabe eines Programms voraus.
- Eine Funktion definieren und aufrufen
- 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 verwendenErgä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 gebenMache Parameter mithilfe von Standardwerten optional, ordne erforderliche und optionale Parameter richtig an und lerne, wann ein Standardwert erstellt wird.
- Parameter und Positionsargumente verwenden
- Übergib mit
returneinen 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 verwendenBeende 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 kombinierenSchreibe 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.
- Einen Wert zurückgeben und verwenden
- Sage voraus, auf welche Variablen eine Funktion zugreifen kann und welche sie ändern kann, übergib Daten über Parameter und Rückgabewerte und verwende
globalnur, wenn es wirklich nötig ist.- Mit lokalen Variablen und Parametern arbeitenErklä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 verwendenLies globale Werte sicher, verstehe den Fehler bei der Zuweisung an einen globalen Namen, verwende die
global-Anweisung richtig und bevorzuge Parameter und Rückgabewerte.
- Mit lokalen Variablen und Parametern arbeiten
- 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 dokumentierenSchreibe einzeilige und mehrzeilige Docstrings nach den üblichen Konventionen und lies sie mit
help(). - Ein Problem in Funktionen zerlegenZerlege 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üfenEntwickle 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.
- Funktionen mit Docstrings dokumentieren
Python-Funktionen einfach erklärt
1Eigene 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
printausgefü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.
2Informationen 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:
| Aufruf | Was 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
TypeErroraus. - 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
| Aufruf | Diagnose |
|---|---|
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
printsteuertsepdie Trennzeichen undendden 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
defausgeführt wird. - Eine veränderliche Liste als Standardwert wird von Aufrufen gemeinsam genutzt, die das Argument auslassen.
- Verwende
Noneund erstelle im Körper eine Liste, wenn für jedes weggelassene Argument eine neue Liste gebraucht wird.
3Ergebnisse 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.
| Operation | Wohin der Wert gelangt |
|---|---|
print(value) | Zeigt ihn für einen Menschen an. |
return value | Gibt 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 valuebeendet 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
returnergibtNone. - 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.
4Den 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 Funktion | Deklaration nötig? |
|---|---|
| Eine globale Einstellung lesen | Nein. |
| Einem globalen Namen einen neuen Wert zuweisen | global name vor der Verwendung. |
| An eine vorhandene globale Liste anhängen | Nein; 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
UnboundLocalErroraus. - Setze
global namevor 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.
5Programme 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
| Form | Hauptzweck |
|---|---|
| Erste Zeichenkette im Körper | Beschreibt die Funktion für den aufrufenden Code und erscheint in help. |
#-Kommentar im Körper | Erklä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)odername.__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
maindie Hilfsfunktionen koordinieren und rufemain()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
| Anzeichen | Prüfung |
|---|---|
Ein Ergebnis ist None | Ein fehlendes return oder ein nicht abgedeckter Pfad. |
| Es erscheint keine Wirkung | Ein fehlender Aufruf oder ein ungenutzter Rückgabewert. |
| Ein plausibles Ergebnis hat die falsche Bedeutung | Vertauschte Argumente. |
NameError | Ein 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
1Eine Funktion schreiben und ihre Aufrufe verfolgen
10 Schritte
- 1Einfü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.
- 2Erklä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.
- 3BeispielDie 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:
greetallein verweist auf das Funktionsobjekt. Es ruft die Funktion nicht auf, undprint(greet)zeigt statt der Begrüßung eine Funktionsbeschreibung an. - 4HerausforderungDie 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, änderereadyzuready(). Der Aufruf würde dann vor der letzten print-Anweisung ausgeführt und „Ready“ und „Waiting“ in getrennten Zeilen ausgeben. - 5TippNamen 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 aninputverdeckt die Funktion, sodass ein späteresinput(...)versucht, Text aufzurufen, und fehlschlägt.Ein unfertiger Körper braucht eine Anweisung. Verwende ein eingerücktes
passals Platzhalter. Ein Kommentar allein ist kein Körper, und ein nicht eingerücktespassstünde stattdessen außerhalb der Funktion. - 6BeispielIn 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 ruftlineauf, sodass banner warten muss, während die Hilfsfunktion ihre Striche ausgibt. Gehe erst zum Titel weiter, wenn die Hilfsfunktion endet. - 7ErklärungEbene für Ebene fortsetzen
Wenn
lineendet, wird der Ablauf bei der Ausgabe des Titels inbannerfortgesetzt. Danach ruft bannerlineein 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.
- 8HerausforderungEinen 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
innerund setzt dann bei seiner nächsten print-Anweisung fort. Erst nachdemouterendet, wird die letzte Anweisung auf Modulebene ausgeführt. Die Reihenfolge der Definitionen allein bestimmt nicht die Reihenfolge der Ausgabe. - 9HerausforderungEine Definition sicher verschieben
Eine Datei definiert
showmit einem Körper, derborderaufruft. Danach definiert sieborderund endet mit einer Schleife, dieshow()zweimal aufruft. Führt die weiter unten stehende Definition der Hilfsfunktion zu einem Fehler, und wie oft wirdborderausgeführt?---reveal---
Das Programm funktioniert: Beide Definitionen wurden ausgeführt, bevor die Schleife
showaufruft. Jeder Aufruf beginntshowbei der ersten Zeile seines Körpers und erreicht einen Aufruf vonborder, 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. - 10ZusammenfassungBei 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.
2Die Parameterstellen belegen
13 Schritte
Speichere diese Einheit, um jede Interaktive Lektion Schritt für Schritt durchzugehen.
- 1EinführungEine Aufgabe mit verschiedenen Werten wiederverwenden
- 2BeispielDie erste und zweite Eingabe zuordnen
- 3ErklärungArgumente vor dem Körper auswerten
- 4HerausforderungDie Argumentanzahl prüfen
- 5ErklärungNamen verwenden, um die Rollen zu zeigen
- 6HerausforderungEine doppelt belegte Stelle korrigieren
- 7TippSchlüsselwortoptionen eingebauter Funktionen lesen
- 8BeispielDie häufige Wahl optional machen
- 9HerausforderungEine optionale Wahl anhand des Namens überspringen
- 10KernaussageEin Standardwert behält den Wert vom Zeitpunkt seiner Erstellung
- 11BeispielErkennen, warum eine Liste als Standardwert Elemente behält
- 12HerausforderungStandardwerte mit benannten Eingaben kombinieren
- 13ZusammenfassungDen Kopf mit dem Aufruf abgleichen
3Werte zurück zum aufrufenden Code verfolgen
14 Schritte
Speichere diese Einheit, um jede Interaktive Lektion Schritt für Schritt durchzugehen.
- 1EinführungBeobachten, was der aufrufende Code erhält
- 2BeispielDen Aufruf durch sein Ergebnis ersetzen
- 3ErklärungBildschirmausgabe und Ergebnis unterscheiden
- 4HerausforderungDen für die Addition verwendeten Wert finden
- 5TippPrüfen, wo der Aufruf ausgeführt wird
- 6BeispielBei der ersten zutreffenden Note anhalten
- 7HerausforderungDie Eingabe zwischen den Zweigen abdecken
- 8KernaussageEinen Vergleich die Frage beantworten lassen
- 9BeispielEinen gefundenen Teiler zurückgeben
- 10HerausforderungEin zu früh zurückgegebenes Erfolgsergebnis korrigieren
- 11BeispielEin zusammengefasstes Ergebnis entpacken
- 12BeispielEin inneres Ergebnis nach außen übergeben
- 13HerausforderungEinen vorzeitigen Pfad mit einem Ergebnis kombinieren
- 14ZusammenfassungPfade und Rückgabewerte gemeinsam verfolgen
4Namen und gemeinsam referenzierte Objekte verfolgen
11 Schritte
Speichere diese Einheit, um jede Interaktive Lektion Schritt für Schritt durchzugehen.
- 1EinführungFragen, wohin der Name gehört
- 2BeispielJedem Aufruf einen eigenen Zähler geben
- 3ErklärungVerdeckte Namen auseinanderhalten
- 4HerausforderungDie Aktualisierung im aufrufenden Code sichtbar machen
- 5BeispielEine gemeinsam referenzierte Liste durch einen Parameter verfolgen
- 6BeispielEine globale Variable ohne Deklaration lesen
- 7KernaussageEine Zuweisung bestimmt den lokalen Gültigkeitsbereich frühzeitig
- 8HerausforderungDen Gültigkeitsbereich einer Aktualisierung wählen
- 9VerbindungDen veränderlichen Wert durch den Aufruf führen
- 10HerausforderungVeränderung eines Objekts und erneute Zuweisung unterscheiden
- 11ZusammenfassungDie Operation benennen, bevor du ihre Wirkung vorhersagst
5Einen Bericht über Testergebnisse entwerfen und prüfen
12 Schritte
Speichere diese Einheit, um jede Interaktive Lektion Schritt für Schritt durchzugehen.
- 1EinführungEin Programm aus klaren Aufgaben erstellen
- 2BeispielDie Beschreibung so platzieren, dass die Hilfe sie findet
- 3ErklärungEinzelheiten ergänzen, die einen Aufruf beeinflussen
- 4HerausforderungDie fehlende Dokumentation finden
- 5ErklärungFür jede Hilfsfunktion eine Aufgabe wählen
- 6BeispielDie Hilfsfunktionen in main verbinden
- 7HerausforderungBerechnung und Anzeige trennen
- 8TippBeim Erstellen ein funktionierendes Programm behalten
- 9BeispielEine Grenze prüfen, die einen Programmfehler aufdecken kann
- 10HerausforderungFinden, wo ein falscher Datentyp hineingelangt
- 11HerausforderungDokumentation und Prüfung in Übereinstimmung halten
- 12ZusammenfassungDie Schnittstelle als Leitfaden für Prüfungen nutzen
Python-Funktionen: Übungsaufgaben
Set 1: Aufrufe lesen und ihre Ergebnisse verfolgen10 Übungsfragen
Frage 1 von 10
Welche Ausgabe erzeugt dieses Programm?
def announce():
print("Open")
print("Ready")
Antwort zeigenAntwort ausblenden
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()
Antwort zeigenAntwort ausblenden
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")
Antwort zeigenAntwort ausblenden
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)
Antwort zeigenAntwort ausblenden
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")
Antwort zeigenAntwort ausblenden
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)
Antwort zeigenAntwort ausblenden
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
Antwort zeigenAntwort ausblenden
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)
Antwort zeigenAntwort ausblenden
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
Antwort zeigenAntwort ausblenden
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
Antwort zeigenAntwort ausblenden
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
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)
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)
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)
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)
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)
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()
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)
Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 9 von 10
Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 10 von 10
> 50 am besten auf?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()
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)
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)
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", []))
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")
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
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)
Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 8 von 10
Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 9 von 10
Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 10 von 10
if score >= 60: fehl, nachdem der aufrufende Code input("Score: ") übergeben hat. Welche Korrektur behebt das Problem mit dem Eingabetyp?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
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")
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="-")
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
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
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)
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
Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 8 von 10
pass. Ihr aufrufender Code addiert das Ergebnis der Hilfsfunktion zu 7 und erhält einen TypeError. Was sollte als Nächstes implementiert werden?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)))
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))
Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Hängst du bei deiner eigenen Aufgabe fest? Hausaufgabenhilfe
Schlüsselbegriffe
A
Argument
area(side + 1, 2) berechnet Python das erste Argument, bevor es den Flächenkörper beginnt.aufrufender Code
banner() die Funktion line() aufruft, ist der Körper von banner der aufrufende Code der Funktion zum Zeichnen der Linie.Aufrufstapel
B
boolesche Funktion
True oder False, oft direkt aus einem Vergleich.return n % 2 == 0 ermöglicht es, is_even(n) direkt als if-Bedingung zu verwenden.D
Debug-Ausgabe
Docstring
E
einzeiliger Docstring
end
end von print steuert den Text, der nach den angezeigten Werten angehängt wird; standardmäßig ist das ein Zeilenumbruch.end="..." kann die nächste print-Anweisung nach den Punkten fortsetzen, statt eine neue Zeile zu beginnen.Entpacken
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
def greet(name, greeting="Hello"): verursacht das Weglassen von name einen Fehler wegen eines fehlenden Arguments.erneute Zuweisung
points = points + 10 ändert den lokalen Parameter und lässt die Punktzahl des aufrufenden Codes unverändert.erwartetes Ergebnis
F
Funktion
print_receipt() aufrufen, wann immer es einen weiteren Beleg anzeigen muss.Funktion mit nutzbarem Rückgabewert
Funktion ohne nutzbaren Rückgabewert
None hinaus kein nutzbares Ergebnis.None erhält.Funktionsaufruf
greet() führt die Begrüßung aus, eine Zeile mit nur greet dagegen nicht.Funktionsdefinition
def-Anweisung mit einem Kopf und einem eingerückten Körper, die eine Funktion unter einem Namen erstellt.greet bei def greet(): und wartet auf einen Aufruf, bevor es den Körper ausführt.Funktionskopf
def, dem Funktionsnamen, runden Klammern für die Parameter und einem Doppelpunkt.def print_line(length): benennt der Kopf die Aufgabe und ihre Eingabe, bevor der Körper beginnt.Funktionskörper
print-Zeilen unter def greet(): gehören beide zum Körper der Funktion.Funktionsplatzhalter
pass bilden einen gültigen Funktionsplatzhalter, dessen Aufrufe bis zur Implementierung allerdings weiterhin None zurückgeben.G
gemischte Argumentübergabe
describe_pet("cat", name="Milo") wird die erste Stelle nach Position und die zweite nach Namen belegt.global-Anweisung
global-Anweisung lässt einen Namen innerhalb einer Funktion bei nachfolgenden Lesezugriffen und Zuweisungen auf die Bindung auf Dateiebene verweisen.global total vor die Verwendung von total in der Funktion, um einen gemeinsam genutzten laufenden Zähler zu aktualisieren.globale Variable
x = 10 auf Modulebene bleibt 10, wenn eine Hilfsfunktion ihr eigenes separates lokales x = 5 setzt.Grenzwerttest
> statt >= verwendet.Gültigkeitsbereich
make_greeting() erstellter Name ist für eine print-Anweisung auf Modulebene nach dem Aufruf nicht verfügbar.H
help
help zeigt Informationen über eine Funktion an, darunter ihre Signatur und ihren gespeicherten Docstring, sofern vorhanden.help(to_fahrenheit), um die Umrechnungsfunktion zu untersuchen, ohne ihr zuerst eine Temperatur zu übergeben.I
inkrementelle Entwicklung
K
Konstante
TAX_RATE = 0.25 lesen, um eine Steuer zu berechnen, ohne den Namen als global zu deklarieren.L
lokale Variable
count = 0 initialisieren, sodass zwei Aufrufe unabhängig voneinander den Wert 1 ausgeben können.M
main
main-Funktion koordiniert die kleineren Aufgaben eines Programms und verbindet Eingaben, Ergebnisse der Hilfsfunktionen und die abschließende Anzeige.main() führt die Schritte eines Berichts über Testergebnisse aus, nachdem alle Definitionen der Hilfsfunktionen ausgeführt wurden.mehrzeiliger Docstring
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.basket=None kann die Funktion innerhalb von if basket is None: eine neue Liste erstellen.O
optionaler Parameter
milk="oat" setzen und einen früheren optionalen Parameter für die Anzahl der Espressos bei seinem Standardwert belassen.P
Parameter
def area(width, height): gibt jedem Flächenaufruf lokale Namen für seine beiden Abmessungen.pass
pass-Anweisung ist ein Platzhalter, der keine Aktion ausführt und einen geplanten Funktionskörper zu gültigem Python macht.pass enthält, kann aufgerufen werden, während ihr eigentliches Ausgabeverhalten noch geschrieben wird.Positionsargument
describe_pet(animal, name) setzt describe_pet("cat", "Milo") den Wert „cat“ in animal ein.Programmablauf
banner() wechseln, dessen Hilfsaufrufe abschließen und dann „End“ ausgeben.prozedurale Abstraktion
letter_grade(avg) verwenden, ohne jeden Schwellenwertvergleich im Körper zu verfolgen.R
return-Anweisung
None.return width * height ermöglicht es dem aufrufenden Code, eine Fläche zu speichern oder in einer weiteren Berechnung zu verwenden.Rückgabepfad
Rückgabewert
area = rectangle_area(4, 2.5) enthält area das zurückgegebene Ergebnis 10,0 zur späteren Verwendung.S
Schlüsselwortargument
describe_pet(name="Milo", animal="cat") belegt die Parameter in einer gut lesbaren Reihenfolge.Schnittstelle
sep
sep von print steuert den Text, der zwischen angezeigten Werten eingefügt wird; standardmäßig ist das ein Leerzeichen.print("a", "b", "c", sep="-") zeigt die drei Buchstaben als „a-b-c“ an.Standardwert
def greet(name, greeting="Hello"): kann ein Aufruf die Begrüßung auslassen und trotzdem den Namen übergeben.T
Traceback
Tupel
return total // people, total % people fasst einen Anteil und einen Rest zusammen.TypeError
TypeError meldet eine ungeeignete Operation auf einem Wert oder einen Aufruf mit einer ungültigen Argumentkombination.TypeError aus.U
UnboundLocalError
UnboundLocalError tritt auf, wenn eine Funktion versucht, einen lokalen Namen zu lesen, bevor dieser lokale Name einen Wert hat.count macht auch ein früheres print(count) lokal, selbst wenn eine globale Variable existiert.V
veränderlicher Standardwert
Veränderung eines Objekts
verborgener Zustand
Verdeckung
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
print(to_fahrenheit(add(10, 15))) läuft die Addition vor der Umrechnung und dann die Ausgabe.vorzeitige Rückgabe
Z
Zerlegung
Über diese Einheit
Erstelle deine eigenen Lernmaterialien
Mach aus deinen Notizen, Folien und Dokumenten Lernleitfäden, Übungsfragen, Karteikarten und 6 weitere Tools.