0%

Objekte darstellen und vergleichen · Übung

Eine lesbare Darstellung mit str() erstellen

Question("What does len('cat') return?", '3', 2) enthält genau die Einzelheiten, die Entwickler in einem Log sehen möchten.

Einer Person, die gerade das Quiz bearbeitet, würdest du das nicht zeigen. Sie möchte den Fragetext und sonst nichts.

Python erlaubt einem Objekt, beide Anfragen unterschiedlich zu beantworten.

Zwei Fragen an ein Objekt

Try it

Drei Zeilen, zwei verschiedene Strings. print verwendete __str__. repr() verwendete __repr__. Die Liste verwendete __repr__ für ihre Inhalte.

Die Aufteilung ist bewusst gewählt:

  • __repr__ ist für Menschen, die am Programm arbeiten: informativ und eindeutig, mit einer konstruktorähnlichen Form, wenn das praktikabel ist.

  • __str__ ist für Menschen, die das Programm verwenden: gut lesbar und mit der Freiheit, Dinge wegzulassen.

__str__ lässt hier die erwartete Antwort vollständig weg. Für eine repr-Darstellung wäre das schlecht; für Text vor dem Beantworten einer Frage ist es genau richtig.

Bei diesen Klassen verwendet auch einfache f-String-Formatierung wie {question} die Methode __str__. Der Zusatz !r, wie in {question!r}, wählt stattdessen __repr__.

Welche Darstellung verwendet print(f"Next: {question}")?

Was passiert, wenn du nur eine Methode definierst

Das solltest du dir merken, denn es entscheidet, welche Methode du zuerst schreibst.

Definierst du nur __repr__, greift str() darauf zurück. Jede Darstellung im Programm verbessert sich auf einmal:

Try it

Definierst du nur __str__, gibt es keinen entsprechenden Rückgriff in die andere Richtung:

Try it

Die Liste zeigt weiterhin die Speicheradresse, ebenso jeder Debugger, jede Logzeile und jede fehlgeschlagene Zusicherung.

Wenn du sowohl die Entwicklerdarstellung als auch die Darstellung für Nutzer verbessern willst, beginne mit __repr__. Ergänze __str__, wenn sich die lesbare Form unterscheiden soll.

Die meisten Klassen brauchen niemals __str__. Ein Response oder ein ScoreReport wird Nutzern nicht direkt gezeigt. Ein __str__, das nur die repr-Darstellung wiederholt, wäre Code ohne Leser.

Formatierung gehört meist an den Rand

Kapitel 6 erklärte, warum Darstellung außerhalb von Domänenklassen bleiben sollte. __str__ scheint diese Regel zu verletzen.

Der Unterschied liegt im Umfang. __str__ beantwortet die Frage „Was ist die einfachste Textform dieses einen Objekts?“ Es sollte nichts über Terminalbreite, Farben, Sprache oder die Anordnung eines Berichts wissen. Diese Entscheidungen gehören zu ScoreReport oder zum Programmeinstieg und ändern sich viel häufiger.

Ein nützlicher Test: Würde sich der String ändern, wenn das Programm auf eine Webseite umzieht, gehört er nicht in __str__.

Die Übung

Du ergänzt beide Methoden in drei Klassen und entscheidest für jede, ob sich ein __str__ lohnt.

Aufgabe

Gib jeder Klasse die Darstellungsmethoden, die sie tatsächlich braucht.

Question erhält beide: eine repr-Darstellung Question('...', '...', 2) und ein __str__ mit What does len('cat') return? (2 points), das niemals die erwartete Antwort verrät.

QuizAttempt erhält beide: die Zusammenfassung QuizAttempt(learner='Mina', response_count=2) als repr-Darstellung und Mina: 2 of 5 points als __str__.

Response erhält nur eine repr-Darstellung: Response(given='3', earned=2). Seine Richtigkeit und seine verdienten Punkte sind Momentaufnahmen vom Eingang der Antwort.

Führe das Programm aus. Die beiden Zeilen mit einer Liste müssen die Entwicklerdarstellung zeigen, die beiden mit einem einzelnen Objekt die lesbare Form.