Tilbake
5.3

5.3 `__str__` og pen objektutskrift

Gjøre et objekt pent utskrivbart med `__str__`, og skrive utskriftsmetoder som delegerer til underobjektenes utskrift.

40 min
7 oppgaver
`__str__`pen objektutskrift
Din fremgang i kapitlet
0 / 7 oppgaver

Forkunnskaper — sist du var her

Kapitlet bygger på kap. 5.1 — Klasser og objekter og
kap. 5.2 — Innkapsling, og bruker
str(...)-konverteringen fra kap. 3.3 — Strenger.

De to tingene du trenger å ha helt klart, friskes opp med kjørt kode.

1. str(tall) gjør et tall om til tekst, slik at det kan skjøtes sammen med
annen tekst med +:

navn = "Sult" aar = 1890 print(navn + " (" + str(aar) + ")")

Utskrift:

Sult (1890)

Uten str(...) rundt tallet stopper programmet, og siste linje i feilmeldingen er TypeError: can only concatenate str (not "int") to str.

2. En metode når objektets verdier med self._x, og returnerer med return:

class Bok:
    def __init__(self, tittel, aar):
        self._tittel = tittel self._aar = aar

    def hent_tittel(self):
        return self._tittel

b = Bok("Sult", 1890)
print(b.hent_tittel())

Utskrift:

Sult

Nå setter vi de to sammen: en metode som bygger en tekst av objektets egne verdier.

Løkke 1 — Hva skjer når du skriver ut et objekt? (~10 min)

Et bibliotek har et Bok-objekt, og du vil bare se hva som står i det. Det nærliggende er å skrive print(b).

Det virker ikke slik du håper. Uten videre gir Python deg noe i denne stilen:

<__main__.Bok object at 0x104a2f130>

Blokken er merket som ikke-kjørbar fordi tallet på slutten er en adresse i maskinens minne og blir forskjellig hver gang programmet kjøres. Det er maskinens svar på «hvilket objekt dette er», og det er ubrukelig for et menneske.

Løsningen er å fortelle Python hvordan objektet skal se ut som tekst. Det
gjør du med spesialmetoden __str__.

`__str__`

Spesialmetoden som returnerer en tekst som beskriver objektet. Python kaller den automatisk når objektet skal skrives ut.

Navnet har to understreker på hver side, som __init__, og du kaller den aldri selv:

class Bok:
    def __init__(self, tittel, aar):
        self._tittel = tittel self._aar = aar

    def __str__(self):
        return self._tittel + " (" + str(self._aar) + ")"

b = Bok("Sult", 1890)
print(b)

Utskrift:

Sult (1890)

Metoden har self som eneste parameter, og den returnerer — den skriver ikke ut. Bruker du print inni i stedet for return, går det galt på en måte som forklares i advarselen lenger nede.

📜`__str__`-malen

Bokas ellevte kodemønster. Malen er kort og alltid den samme:

    def __str__(self):
        return "..." + self._tekstfelt + " " + str(self._tallfelt)

Blokken er en mal med plassholdernavn og er derfor merket som ikke-kjørbar.

Tre regler:

1. return, aldri print. Metoden leverer en tekst; det er den som kaller,
som bestemmer om teksten skal vises.
2. str(...) rundt hvert tall. Tekst pluss tall stopper programmet.
Tekstfelt trenger det ikke, men det skader ikke å ta det med.
3. Mellomrom og skilletegn skrives inn selv. + skjøter uten å legge til
noe, i motsetning til komma i et print-kall.

Formen på teksten bestemmer du. Ber oppgaven om et bestemt format, følg det tegn for tegn — det er den slags detalj som rettes strengt.

✏️Eksempel 1: Fra ubrukelig utskrift til lesbar linje

Gi klassen Medlem på et treningssenter en __str__ som gjør at
print(medlem) viser navn, medlemsnummer og antall besøk på én linje.

Metoden bygger én tekst av de tre verdiene, med skilletegn skrevet inn for hånd:

class Medlem:
    def __init__(self, navn, nummer):
        self._navn = navn self._nummer = nummer self._besok = 0

    def registrer_besok(self):
        self._besok = self._besok + 1

    def __str__(self):
        return self._navn + " (nr " + str(self._nummer) + "), " + str(self._besok) + " besok"

m = Medlem("Ada", 104)
m.registrer_besok()
m.registrer_besok()
print(m)

Utskrift:

Ada (nr 104), 2 besok

Legg merke til de tre str(...)-kallene. self._navn er allerede tekst og
trenger ingen, men self._nummer og self._besok er tall. Uten konverteringen stopper programmet med TypeError: can only concatenate str (not "int") to str.

Slik ville sensor sett på det: tre ting gir uttelling hver for seg — at
metoden heter __str__ med riktige understreker, at den bruker return, og at tallene er konvertert. Hadde du glemt ett str(...), ville de to andre fortsatt telt.

Merk at teksten er skrevet uten æ, ø og å, som all kode i denne boka. «besok»
i stedet for «besøk» er den vanlige omskrivingen.

📝Oppgave 1

(Innstegsoppgave — gjengivelse.) Klassen Rett i en kantine har
self._navn og self._pris.

a) Skriv __str__ slik at print(rett) gir for eksempel
Fiskesuppe: 89 kr.

b) Hvorfor må prisen gjennom str(...)?

c) Hva ville print(rett) gitt hvis klassen ikke hadde noen __str__?

Løkke 2 — __str__ mot en skriv-metode (~10 min)

Det finnes to måter å få et objekt til å vise seg fram på, og eksamensoppgaver ber om begge. Forskjellen er liten i kode og stor i bruk.

En __str__ returnerer en tekst. En skriv-metode skriver den ut. Den første kan brukes videre — legges i en liste, skjøtes med annen tekst, sendes til en annen metode. Den andre er ferdig i det øyeblikket den kjører.

`str(objekt)` og `print(objekt)`

De to måtene __str__ blir kalt på — begge automatisk, ingen av dem av deg.

print(objekt) kaller __str__ og skriver resultatet. str(objekt) kaller
__str__ og gir deg teksten, slik at du kan bruke den videre:

class Bok:
    def __init__(self, tittel):
        self._tittel = tittel

    def __str__(self):
        return "Bok: " + self._tittel

b = Bok("Sult")
linje = str(b)
print(linje + " | " + str(b))

Utskrift:

Bok: Sult | Bok: Sult

Det er dette som gjør __str__ mer verdt enn en skriv-metode: teksten kan brukes til noe. Du kan skjøte den, sammenligne den eller legge den i en liste.

Skriv-metode

En vanlig metode som skriver ut i stedet for å returnere:

class Bok:
    def __init__(self, tittel, aar):
        self._tittel = tittel self._aar = aar

    def skriv(self):
        print(self._tittel, self._aar)

b = Bok("Sult", 1890)
b.skriv()

Utskrift:

Sult 1890

Navnet er fritt — skriv, skriv_ut, vis. Metoden returnerer ingenting, og verdien kan derfor ikke brukes videre.

Legg merke til komma i print-kallet. Komma skiller argumentene med ett
mellomrom
og konverterer tall automatisk, så du slipper både + og str(...).
Det er den store praktiske forskjellen fra __str__, der du må skrive begge deler selv.

Ber oppgaven om «en metode som skriver ut objektet», er dette svaret. Ber den om
«at objektet kan skrives pent ut med print», er svaret __str__.

✏️Eksempel 2: Samme klasse med begge deler

Gi klassen Sykkel både en __str__ og en skriv-metode, og vis når hver av dem er nyttig.

Klassen får begge, og bruken viser forskjellen:

class Sykkel:
    def __init__(self, kode, stativ):
        self._kode = kode self._stativ = stativ

    def __str__(self):
        return self._kode + " @ " + self._stativ

    def skriv(self):
        print("Sykkel", self._kode, "staar i", self._stativ)

s = Sykkel("R31", "Blindern")
print(s)
s.skriv()

linjer = []
linjer.append(str(s))
linjer.append("R48 @ Majorstuen")
print(len(linjer), linjer[0])

Utskrift:

R31 @ Blindern
Sykkel R31 staar i Blindern
2 R31 @ Blindern

De to første linjene ser like nyttige ut, men bare den ene teksten kan gjenbrukes.
Nederst legges den i en liste, og det kunne like gjerne vært en fil, en sammenligning eller en lengre rapport. Skriv-metoden har ingen slik verdi å gi fra seg.

Slik ville sensor sett på det: ber oppgaven om «en metode som gjør at
objektet kan skrives ut med print», er __str__ det riktige svaret, og en skriv-metode gir bare delvis uttelling. Ber den om «en metode som skriver ut opplysningene», er skriv-metoden riktig. Les hvilket av de to verbene som står der.

Merk @-tegnet i teksten. Det er et helt vanlig tegn i en streng, og det er
lov å bruke det som skilletegn. Æ, ø og å er det derimot ikke, som ellers i bokas kode.

📝Oppgave 2
Eksamensnivå, sjanger A

Hva skriver programmet ut?

class Vare:
    def __init__(self, navn, antall, pris):
        self._navn = navn self._antall = antall self._pris = pris

    def __str__(self):
        return self._navn + " x" + str(self._antall)

    def hent_verdi(self):
        return self._antall * self._pris

v = Vare("skrue", 4, 3)
print(v)
print(v, v.hent_verdi())
print(str(v) + "!")

📝Oppgave 3
Eksamensnivå, sjanger…

En kollektivrute skal kunne skrives ut på formen Rute 20: Blindern - Toyen (14 passasjerer).

a) Skriv klassen Rute med konstruktør som tar rutenummer, startsted og
endested, og et passasjerantall som starter på 0.

b) Skriv __str__ som gir nøyaktig formen over.

c) Legg til paa(self, antall) og vis at utskriften følger med.

Løkke 3 — Delegering: la hvert objekt skrive seg selv (~12 min)

Nå kommer mønsteret som er fast delkrav i den store oppgaven.

Et bibliotek holder mange bøker. Skal biblioteket skrive ut hele samlingen sin, har det to valg: enten grave i hver boks verdier selv, eller be hver bok om å skrive seg selv.

Det siste heter delegering, og det er alltid riktig svar. Grunnen er den samme som i kap. 5.2: boka vet hvordan en bok skal vises, og biblioteket skal slippe å vite det.

📜Delegerings-malen

Bokas tolvte kodemønster, og kjernen i Oppgave 4:

class Container:
    def __init__(self):
        self._elementer = []

    def legg_til(self, e):
        self._elementer.append(e)

    def skriv_alle(self):
        for e in self._elementer:
            print(e)

Blokken er en mal med plassholdernavn og er merket som ikke-kjørbar.

Løkka går gjennom samlingen og lar print(e) kalle hvert underobjekts
__str__. Ytterklassen skriver ikke ett eneste felt selv.

Alternativet — å skrive print(e.hent_tittel(), e.hent_aar()) inne i løkka —
gir dårligere uttelling
, fordi visningen da er duplisert: endrer boka format, må biblioteket endres også. Og verst av alt er print(e._tittel), som i tillegg er feilkode #11, direkte tilgang til en instansvariabel utenfra.

✏️Eksempel 3: `Bibliotek` som delegerer utskriften til hver `Bok`

La klassen Bibliotek holde flere Bok-objekter i en liste, og gi den en metode som skriver ut hele samlingen ved å be hver bok om å vise seg selv.

To klasser, der den ytre bare holder styr på samlingen:

class Bok:
    def __init__(self, tittel, aar):
        self._tittel = tittel self._aar = aar

    def __str__(self):
        return self._tittel + " (" + str(self._aar) + ")"

class Bibliotek:
    def __init__(self, navn):
        self._navn = navn self._boker = []

    def legg_til(self, bok):
        self._boker.append(bok)

    def skriv_alle(self):
        print("Samling:", self._navn)
        for b in self._boker:
            print(" -", b)

bib = Bibliotek("Deichman")
bib.legg_til(Bok("Sult", 1890))
bib.legg_til(Bok("Markens grode", 1917))
bib.skriv_alle()

Utskrift:

Samling: Deichman
 - Sult (1890)
 - Markens grode (1917)

Linjen print(" -", b) er hele delegeringen. b er et Bok-objekt, og
print kaller boka sin egen __str__. Bibliotek vet ikke — og trenger ikke å vite — at en bok vises med tittel og årstall i parentes.

Prøv tanken: skal bøkene senere vises med forfatter i tillegg, endrer du én
metode i Bok, og Bibliotek merker ingenting. Det er den samme gevinsten som i
kap. 5.2, nå mellom to klasser.

Slik ville sensor sett på det: fem ting gir uttelling. self._boker = [] i
konstruktøren, append i legg_til, løkka i skriv_alle, at utskriften delegeres i stedet for å hentes felt for felt, og at metoden heter noe annet enn elementets. Hadde du skrevet print(" -", b.hent_tittel()), ville strukturen vært riktig og trekket lite — men delegeringspoenget hadde gått tapt.

— naturlig pausepunkt —

📝Oppgave 4
Eksamensnivå, sjanger A

Hva skriver programmet ut?

class Spill:
    def __init__(self, tittel, maks):
        self._tittel = tittel self._maks = maks

    def __str__(self):
        return self._tittel + " (" + str(self._maks) + ")"

class Klubb:
    def __init__(self):
        self._spill = []

    def legg_til(self, s):
        self._spill.append(s)

    def skriv_alle(self):
        for s in self._spill:
            print(s)
        print("Antall:", len(self._spill))

k = Klubb()
k.legg_til(Spill("Kolonier", 4))
k.legg_til(Spill("Sjakk", 2))
k.skriv_alle()

📝Oppgave 5
Eksamensnivå, sjanger…

En resirkuleringsstasjon har flere containere, hver med et materiale og en fyllingsgrad i prosent.

a) Skriv klassen Container med __str__ på formen glass: 40 %.

b) Skriv klassen Stasjon som holder containerne i en liste, med
legg_til(self, c) og en metode som skriver ut alle.

c) Hva skal metoden i b) hete, og hvorfor ikke skriv?

Løkke 4 — Delegering med en ordbok (~8 min)

Underobjektene ligger ikke alltid i en liste. Skal du kunne slå opp på et navn eller et nummer, er en ordbok fra
kap. 3.2 et bedre valg — og det er formen den store oppgaven ofte bruker.

Delegeringen er akkurat den samme; bare løkka ser litt annerledes ut.

Delegering over en ordbok

Løkka over en ordbok gir deg nøklene. Objektet henter du med et oppslag:

class Bok:
    def __init__(self, tittel):
        self._tittel = tittel

    def __str__(self):
        return "Bok: " + self._tittel

boker = {}
boker["sult"] = Bok("Sult")
boker["vaar"] = Bok("Vaar")
for n in boker:
    print(n, "->", boker[n])

Utskrift:

sult -> Bok: Sult vaar -> Bok: Vaar

Rekkefølgen følger den de ble satt inn i. Verdien boker[n] er et helt vanlig objekt, så print kaller dets __str__ som før.

Nøkkelen er ofte navnet, og verdien objektet. Da har du både oppslag og
gjennomløping i samme struktur — derfor er ordboka så vanlig i Oppgave 4.

✏️Eksempel 4: Full modell på eksamensnivå — treningssenter med saler

Et treningssenter holder salene sine i en ordbok fra salnavn til Sal-objekt.
Skriv de to klassene med __str__ og en utskriftsmetode som delegerer, pluss en metode som finner én sal på navn.

Ordboka gir både oppslag og gjennomløping:

class Sal:
    def __init__(self, navn, kapasitet):
        self._navn = navn self._kapasitet = kapasitet

    def hent_navn(self):
        return self._navn

    def __str__(self):
        return self._navn + " (" + str(self._kapasitet) + " plasser)"

class Senter:
    def __init__(self, sted):
        self._sted = sted self._saler = {}

    def legg_til(self, sal):
        self._saler[sal.hent_navn()] = sal

    def finn(self, navn):
        if navn in self._saler:
            return self._saler[navn]
        return None

    def skriv_alle(self):
        print("Senter:", self._sted)
        for n in self._saler:
            print(" -", self._saler[n])

senter = Senter("Toyen")
senter.legg_til(Sal("Speilsal", 20))
senter.legg_til(Sal("Spinning", 14))
senter.skriv_alle()
print(senter.finn("Spinning"))
print(senter.finn("Basseng"))

Utskrift:

Senter: Toyen
 - Speilsal (20 plasser)
 - Spinning (14 plasser)
Spinning (14 plasser)
None

Fire ting er verdt å merke seg.

legg_til bruker salens egen aksessor til å finne nøkkelen:
self._saler[sal.hent_navn()] = sal. Senteret bestemmer altså ikke navnet selv, det spør salen. Å skrive sal._navn her ville vært feilkode #11.

finn sjekker med if navn in self._saler: før den slår opp. Uten sjekken stopper programmet på en nøkkel som ikke finnes — det er feilkode #14, å slå opp noe som ikke er lagt inn.

Siste linje skriver None, fordi finn("Basseng") ikke fant noe. None er
Pythons ord for «ingen verdi», og print viser det med stor forbokstav.

Og skriv_alle heter ikke skriv, etter navneregelen.

Slik ville sensor sett på det: dette er en typisk 12–15-poengs deloppgave i
Oppgave 4, og poengene ligger spredt: ordboka i konstruktøren, innsettingen med riktig nøkkel, if navn in ...-sjekken, return None-grenen, løkka, og delegeringen. Mangler én av dem, står de andre.

📝Oppgave 6
Eksamensnivå, sjanger A

Hva skriver programmet ut?

class Medlem:
    def __init__(self, navn, timer):
        self._navn = navn self._timer = timer

    def hent_timer(self):
        return self._timer

    def __str__(self):
        return self._navn + "/" + str(self._timer)

class Sentral:
    def __init__(self):
        self._medlemmer = {}

    def legg_til(self, m, nokkel):
        self._medlemmer[nokkel] = m

    def totalt_antall_timer(self):
        total = 0 for n in self._medlemmer:
            total = total + self._medlemmer[n].hent_timer()
        return total

    def skriv_alle(self):
        for n in self._medlemmer:
            print(n, self._medlemmer[n])

s = Sentral()
s.legg_til(Medlem("Ada", 12), "ada")
s.legg_til(Medlem("Nora", 7), "nora")
s.legg_til(Medlem("Ada", 3), "ada")
s.skriv_alle()
print(s.totalt_antall_timer())

📝Oppgave 7
Eksamensnivå, sjanger F

En brettspillklubb har medlemmer, og hvert medlem har et navn og en liste over spill det eier.

a) Skriv klassen Medlem med __str__ på formen Ada (2 spill), og en
metode legg_til_spill(self, tittel).

b) Skriv klassen Klubb som holder medlemmene i en ordbok fra navn til
Medlem-objekt, med meld_inn(self, medlem) og skriv_alle(self).

c) Legg til en metode i Klubb som gir det samlede antall spill i klubben.

d) Hvorfor kan ikke metoden i c) hete det samme som noen metode i Medlem?

API- og konstruksjonsliste

Begrepsbank

Begrepsbanken er flashcard- og repetisjonsstoff — den gjentar det du nettopp har lest. Hopp trygt over ved førstegangslesing; tidsanslaget for kapitlet gjelder kjernestoffet.

Spesialmetode

En metode med to understreker på hver side av navnet, som Python kaller automatisk — du kaller den aldri selv.

I denne boka finnes bare to: __init__, som kjører når objektet lages, og
__str__, som kjører når objektet skal bli tekst.

Blander du dem, er symptomet lett å kjenne igjen: skriver du __str__ der
__init__ skulle stått, får objektet ingen verdier i det hele tatt.

Delegering

At en klasse ber et underobjekt om å gjøre jobben, i stedet for å gjøre den selv.

I dette kapitlet er jobben utskrift: Bibliotek lar hver Bok vise seg selv med sin egen __str__. Senere delegeres også telling, søk og oppdatering.

Kjennetegnet i koden er en løkke der kroppen er ett kall på et underobjekt, og ingen felt hentes ut. Det motsatte — at ytterklassen graver i underobjektets verdier — er både dårligere kode og dårligere uttelling.

Navneregelen for containere

En metode i denne boka kaller aldri en metode med samme navn — verken på seg selv eller på et underobjekt.

Elementet har skriv(), containeren har skriv_alle(). Elementet har
antall_spill(), containeren har totalt_antall_spill().

Regelen har to grunner: navnene beskriver ulike jobber, og en metode som ser ut som om den kaller seg selv, ligner på rekursjon, som er utenfor pensum i dette emnet.

Format som del av bestillingen

Når en oppgave oppgir hvordan utskriften skal se ut, er formatet en del av oppgaven og rettes deretter.

Skriv formatet av på papir før du koder, og marker hvert mellomrom, hvert skilletegn og hver parentes. Rute 20: Blindern - Toyen (14 passasjerer) inneholder fem slike detaljer.

Er formatet ikke oppgitt, velger du selv — men velg noe som er lett å lese, og hold det likt for alle objektene av samme klasse.

Tekst mot utskrift

Skillet som avgjør om en metode skal bruke return eller print.

En metode som lager en tekst, returnerer den, og den som kaller, bestemmer hva som skjer videre. En metode som viser noe, skriver ut, og da er saken avgjort.

__str__ er alltid av den første typen. Det er nettopp derfor den er mer verdt enn en skriv-metode: teksten kan legges i en liste, skjøtes med annen tekst eller sammenlignes.

Minneadressen i standardutskriften

Det Python viser når en klasse mangler __str__: klassenavnet og et sekskantsifret tall, som <__main__.Bok object at 0x104a2f130>.

Tallet er hvor objektet ligger i maskinens minne, og det er forskjellig hver gang programmet kjøres. Derfor kan en slik utskrift aldri være fasit i en sporingsoppgave.

Ser du den i din egen kjøring, betyr det bare at klassen mangler __str__.

Å bygge en lang tekst

Skal __str__ sette sammen mange biter, blir linjen lang. To ryddige måter:

Sett parenteser rundt hele uttrykket og del over flere linjer — Python leser innholdet i en parentes som én sammenhengende linje. Eller bygg teksten i steg med en lokal variabel og returner den til slutt.

Begge er like riktige. Velg den som gjør formatet lettest å kontrollere mot bestillingen.

`None` i en utskrift

Pythons ord for «ingen verdi». Skrives ut med stor forbokstav.

Du møter den to steder i dette kapitlet: som returverdi fra en metode som glemte
return, og som ærlig svar fra en søkemetode som ikke fant noe.

Det siste er riktig og ønsket. return None når et søk mislykkes, er bedre enn å returnere en tom tekst — den som kaller, kan da sjekke med if svar != None:.

Container-klasse

En klasse hvis viktigste jobb er å holde mange objekter av en annen klasse:
Bibliotek med bøker, Klubb med medlemmer, Senter med saler.

Den kjennes igjen på tre trekk: en samling i konstruktøren ([] eller {}), en
legg_til-metode, og én eller flere metoder som løper gjennom samlingen.

Hver eneste Oppgave 4 inneholder minst én slik klasse. Mønsteret er derfor verdt å kunne i fingrene, og det bygges ferdig i
kap. 6.2.

Liste eller ordbok for samlingen

Valget avgjøres av ett spørsmål: skal du slå opp på et navn eller et nummer?

Er svaret ja, bruk en ordbok med det navnet som nøkkel og objektet som verdi. Er svaret nei — du skal bare gå gjennom alle — er en liste enklere.

En ordbok kan aldri ha to like nøkler. Legger du inn samme navn to ganger,
overskrives det første objektet uten en advarsel. Det er verdt å huske både
når du koder og når du sporer.

Å bruke en aksessor som nøkkel

Formen containeren bruker når objektet selv vet hva det heter:
self._saler[sal.hent_navn()] = sal.

Containeren spør altså objektet i stedet for å bestemme navnet selv. Alternativet
self._saler[sal._navn] = sal er feilkode #11, direkte tilgang til en instansvariabel utenfra.

Dette er den vanligste formen feilkode #11 tar når to klasser samarbeider — og den vanligste i den store oppgaven.

Sjekk før oppslag
if navn in self._saler: før self._saler[navn].

Uten sjekken stopper programmet på en nøkkel som ikke finnes, og siste linje i feilmeldingen er KeyError med nøkkelen som mangler. Det er feilkode #14.

Standardformen på en søkemetode er derfor tredelt: sjekk, returner objektet hvis det finnes, og returner None ellers.

Hvorfor `__str__` leses på nytt hver gang
__str__ husker ingenting. Den leser instansvariablene i det øyeblikket den kalles, og bygger teksten på nytt.

Derfor endrer utskriften seg av seg selv når objektet endres — du trenger ikke å kalle noe for å «oppdatere» teksten.

Det er også grunnen til at __str__ aldri skal lagre noe i en instansvariabel.
Metoden skal lese og returnere, ingenting annet.

Å velge mellom `__str__` og skriv-metode

Les verbet i oppgaveteksten.

«Objektet skal kunne skrives pent ut med print» eller «gi klassen en metode som gjør objektet utskrivbart» betyr __str__.

«Skriv en metode som skriver ut opplysningene om …» betyr en vanlig
skriv-metode.

Er du i tvil, skriv __str__ — den kan alltid brukes av en skriv-metode etterpå, mens det ikke går den andre veien.

Repetisjon — de seks setningene som må sitte

Dette kapitlet er skrevet av Anthropics toppmodeller (Claude Opus og Claude Fable) og er foreløpig ikke manuelt gjennomgått — kvalitetskontrollen gjøres av uavhengige KI-agenter, og innmeldte feil rettes fortløpende. Funnet en feil? Meld fra, så retter vi den. Les mer om hvordan innholdet lages.

Skolesaga er en uavhengig læringsressurs og er ikke tilknyttet eller godkjent av Universitetet i Oslo. Dette er ikke offisielt studiemateriell. Les mer.