0%

Dataclasses und Wertobjekte · Übung

Einen unveränderlichen Wert ersetzen

Ein eingefrorener Wert lässt sich nicht bearbeiten. Programme brauchen trotzdem eine Version, in der eine Angabe anders ist.

So verhalten sich Strings bereits:

Try it

Das Original bleibt erhalten, und der Vorgang gibt einen neuen Wert zurück.

Ausgewählte Felder ersetzen

dataclasses.replace kopiert eine Dataclass und ändert dabei die genannten Felder:

Try it

Jedes im Aufruf nicht genannte Feld wird kopiert. Das Original bleibt unangetastet.

Eine kleine Domänenfunktion kann der Änderung einen nützlichen Namen geben:

def without_seconds(duration):
    return replace(duration, seconds=0)

Was tut replace(question, points=5)?

Verwende Ersetzen, wenn sowohl der alte als auch der neue Wert eine Bedeutung hat. Eine angepasste Frage löscht nicht die Tatsache, dass ihre frühere Version existierte.

Die Übung schreibt zwei eng benannte Umwandlungen und prüft, ob jedes Original unangetastet bleibt.

Aufgabe

Schreibe zwei Funktionen, die mit dataclasses.replace neue Question-Werte erzeugen.

worth_more(question, extra) gibt eine Frage zurück, die extra Punkte mehr wert ist.

retitled(question, prompt) gibt eine Frage mit dem neuen Fragetext zurück.

Jede Funktion muss die ursprüngliche Frage unverändert lassen und jedes Feld erhalten, dessen Änderung nicht angefordert wurde.

Das __post_init__ von Question erhält die bisherigen Gültigkeitsregeln. Daher müssen ein extra, das zu null oder negativen Punkten führen würde, und ein leerer Ersatzfragetext über die gewöhnliche Objekterzeugung ValueError auslösen.