Slik tilpasser du __repr__ og __str__ i Python

Lær forskjellen mellom __repr__ og __str__ i Python. Tilpass hvordan objektene dine vises som tekst.

Videoforhåndsvisning

Opprett konto for å se video

Det er helt gratis og tar under 30 sekunder

Opprett gratis kontoHar du konto? Logg inn

Du printer et objekt og får <__main__.Circle object at 0x7f3b2c>. En minneadresse. Ikke fargen, ikke radiusen, ingenting nyttig. Python vet ikke hva du synes er viktig informasjon om objektet ditt, med mindre du forteller det. Det er jobben til __repr__ og __str__.

Hvorfor Python printer en minneadresse

Når du kaller print() på et objekt, leter Python etter en metode som kan gi en tekstrepresentasjon. Finner den ingen, faller den tilbake til standardoppførselen: klassenavnet og minneadressen. Det er teknisk korrekt, men fullstendig ubrukelig for feilsøking.

Python sjekker to metoder i rekkefølge: først __str__, deretter __repr__. Definerer du ingen av dem, får du minneadressen. Definerer du bare __repr__, brukes den overalt. Definerer du begge, velger Python basert på konteksten.

__repr__ er for utviklere

__repr__ skal gi en utvetydig representasjon av objektet, primært for feilsøking. Ideelt sett skal den returnere en streng som kan gjenskape objektet. Har du en sirkel med rød farge og radius 5 i centimeter, bør __repr__ returnere noe som ligner Circle("rød", 5, "cm").

Slik definerer du den:

  • def __repr__(self): tar bare self som parameter.
  • Returner en f-streng med verdiene: return f"Circle('{self.color}', {self.radius}, '{self.unit}')"
  • __repr__ kalles automatisk når du skriver objektnavnet i en interaktiv Python-sesjon, eller når objektet vises i en liste.

Konvensjonen er at __repr__ bør se ut som gyldig Python-kode. Det betyr at en annen utvikler kan kopiere teksten, lime den inn i Python, og faktisk opprette et likeverdig objekt. Det er ikke alltid mulig (noen objekter er for komplekse), men det er målet.

__str__ er for brukere

__str__ skal gi en lesbar, pen representasjon ment for sluttbrukere. For en sirkel kan __str__ returnere "Rød sirkel med radius 5 cm" i stedet for den tekniske __repr__-formen.

Python kaller __str__ i to hovedsituasjoner:

  • print(objekt) bruker alltid __str__ hvis den finnes.
  • f"Sirkelen er {objekt}" bruker __str__ når du setter objektet inn i en f-streng.
  • str(objekt) kaller også __str__.

Hvis __str__ ikke er definert, faller Python tilbake til __repr__. Det betyr at du alltid bør definere __repr__ først. Da har du en fungerende tekstrepresentasjon overalt, og du kan legge til __str__ etterpå for penere utskrift der det trengs.

Repr og str i praksis: en sirkelklasse

Si at du har en Circle-klasse med egenskapene color, radius og unit, pluss metoder for å beregne omkrets og areal. Med __repr__ kan du inkludere alt i utskriften:

  • Farge: self.color
  • Radius: self.radius og self.unit
  • Omkrets: kall self.circumference() direkte i f-strengen.
  • Areal: kall self.area() direkte i f-strengen.

Nå gir print(circle) deg all informasjon du trenger i en linje. Lager du en ny sirkel med andre verdier, får du automatisk oppdaterte tall. Du slipper å skrive separate print-setninger for hver egenskap.

Når du trenger begge

For enkle klasser holder det ofte med bare __repr__. Men når objektene dine vises til brukere (i et brukergrensesnitt, i logger, i rapporter), gir __str__ deg muligheten til å tilpasse utskriften uten å påvirke feilsøkingsvisningen.

Et godt eksempel: en Dato-klasse. __repr__ returnerer Dato(2024, 3, 15) for utvikleren. __str__ returnerer "15. mars 2024" for brukeren. Begge er nyttige i ulike situasjoner, og Python velger riktig basert på konteksten.

I interaktive Python-sesjoner (REPL) brukes __repr__ når du bare skriver objektnavnet og trykker Enter. print() bruker __str__. Det betyr at du kan ha to forskjellige visninger av samme objekt uten ekstra arbeid.

F-strenger og repr()

I f-strenger kan du velge hvilken metode som brukes med formatspesifikatorer. f"{objekt}" kaller __str__, mens f"{objekt!r}" kaller __repr__. Det !r-suffikset er nyttig i logging og feilsøking der du vil se den tekniske representasjonen midt i en lesbar setning.

Du kan også kalle repr(objekt) og str(objekt) som vanlige funksjoner. repr() kaller __repr__, str() kaller __str__. Det gir deg full kontroll over hvilken representasjon du får, uavhengig av konteksten.

Tommelfingerregler for repr og str

Definer alltid __repr__. Det er den viktigste av de to fordi den brukes som fallback overalt. Gjør den så informativ som mulig. Inkluder klassenavn og de viktigste egenskapene.

Definer __str__ når objektet ditt skal vises til sluttbrukere eller i formatert output. Hold den lesbar og konsis. Dropp tekniske detaljer som klassenavnet.

Hold __repr__ utvetydig. To objekter med forskjellige verdier bør aldri ha lik __repr__. Det gjør feilsøking mye enklere fordi du umiddelbart ser forskjellen mellom objekter i en liste eller i en feilmelding.

Neste steg

Med __repr__ og __str__ på plass kan objektene dine kommunisere tydelig. For å bygge mer avanserte klasser, forklarer artikkelen om arv i Python hvordan subklasser arver og overstyrer representasjonsmetodene fra foreldreklassen. Vil du forstå grunnlaget bedre, viser artikkelen om klasser i Python hvordan du bygger klasser fra bunnen av. Pythons offisielle dokumentasjon for __repr__ gir den fulle spesifikasjonen.

Denne artikkelen bygger på kurset Python – objektorientert programmering på Utdannet.no. I kurset jobber du med __repr__, __str__ og andre spesialmetoder gjennom praktiske eksempler, og du får oppgaver der du bygger klasser med tilpasset representasjon og beregningsmetoder.