0%

Objecten weergeven en vergelijken · oefening

Maak een str() voor gebruikers

Question("What does len('cat') return?", '3', 2) is het soort detail dat een ontwikkelaar in een log wil zien.

Het is niet wat je een cursist zou tonen die de quiz maakt. Die wil de vraagtekst en verder niets.

Python laat een object op beide verzoeken verschillend antwoorden.

Twee vragen die een object krijgt

Try it

Drie regels, twee verschillende strings. print gebruikte __str__. repr() gebruikte __repr__. De lijst gebruikte __repr__ voor de inhoud.

De scheiding is bewust:

  • __repr__ is voor degene die aan het programma werkt: informatief en ondubbelzinnig, met een vorm die op een constructor lijkt wanneer dat praktisch is.

  • __str__ is voor degene die het programma gebruikt: leesbaar en vrij om dingen weg te laten.

__str__ laat hier het antwoord volledig weg. Dat zou een verschrikkelijke repr zijn, maar is precies goed voor tekst die je toont aan iemand die de vraag gaat beantwoorden.

Voor deze klassen gebruikt gewone f-stringopmaak zoals {question} ook __str__. !r toevoegen, zoals in {question!r}, selecteert in plaats daarvan __repr__.

Welke uitvoer gebruikt print(f"Next: {question}")?

Wat er gebeurt als je er maar één definieert

Dit onderdeel is het onthouden waard, omdat het bepaalt welke methode je eerst schrijft.

Definieer alleen __repr__ en str() valt daarop terug. Elke weergave in het programma verbetert meteen:

Try it

Definieer alleen __str__ en er is geen terugval in de andere richting:

Try it

De lijst toont nog steeds het geheugenadres, net als elke debugger, logregel en mislukte assertie.

Als je zowel de weergave voor ontwikkelaars als die voor gebruikers verbetert, begin dan met __repr__. Voeg __str__ toe wanneer de leesbare vorm moet verschillen.

De meeste klassen hebben nooit __str__ nodig. Een Response of een ScoreReport toon je niet rechtstreeks aan een gebruiker. Ze een __str__ geven die alleen de repr herhaalt, is code zonder lezer.

Opmaak hoort meestal aan de rand

Hoofdstuk 6 stelde dat presentatie buiten domeinklassen moet blijven. __str__ lijkt die regel te schenden.

Het verschil zit in de reikwijdte. __str__ beantwoordt de vraag ‘wat is de eenvoudigste tekstvorm van dit ene object?’ Die hoort niets te weten over terminalbreedte, kleur, taal of de indeling van een rapport. Die beslissingen horen bij ScoreReport of bij de ingang van het programma en veranderen veel vaker.

Een nuttige toets: als de string zou veranderen wanneer het programma naar een webpagina verhuist, hoort die niet in __str__.

De oefening

Je voegt beide methoden toe aan drie klassen en beslist voor elke klasse of een __str__ zijn plek verdient.

Opdracht

Geef elke klasse de weergavemethoden die die echt nodig heeft.

Question krijgt beide: een repr die Question('...', '...', 2) luidt en een __str__ die What does len('cat') return? (2 points) luidt en nooit het antwoord onthult.

QuizAttempt krijgt beide: een overzichtsrepr die QuizAttempt(learner='Mina', response_count=2) luidt en een __str__ die Mina: 2 of 5 points luidt.

Response krijgt alleen een repr die Response(given='3', earned=2) luidt. De juistheid en verdiende punten zijn momentopnamen van toen het antwoord binnenkwam.

Voer het programma uit. De twee regels die een lijst afdrukken moeten de ontwikkelaarsvorm tonen en de twee die één object afdrukken moeten de leesbare vorm tonen.