Slik bruker du egenskaper og property i Python

Lær om egenskaper i Python-klasser. Property-dekoratoren, getter, setter og deleter forklart.

Videoforhåndsvisning

Opprett konto for å se video

Det er helt gratis og tar under 30 sekunder

Opprett gratis kontoHar du konto? Logg inn

Du har en klasse med en alder-egenskap, og noen setter den til -5. Eller en radius som plutselig blir en tekststreng. Når egenskapene på objektene dine kan endres fritt utenfra, mister du kontrollen. Property i Python gir deg en elegant måte å beskytte dataene, uten å tvinge brukerne av klassen til å endre hvordan de skriver koden sin.

Direkte tilgang fungerer, til det ikke gjør det

I Python kan du lese og endre egenskaper direkte. Har du et objekt volvo med egenskapen model, skriver du bare volvo.model = "S80" for å endre den. Det er enkelt og fungerer fint i mange tilfeller.

Problemet oppstår når du trenger kontroll. Kanskje du vil sikre at en alder aldri er negativ, eller at en farge alltid er en gyldig streng. Med direkte tilgang har du ingen mulighet til å validere verdien før den settes. Det er her @property kommer inn.

Hva @property gjør i Python

@property er en dekoratør som lar deg definere en metode, men bruke den som om den var en vanlig egenskap. Brukeren av klassen skriver fortsatt objekt.alder i stedet for objekt.get_alder(). Forskjellen er at koden din kjøres bak kulissene hver gang egenskapen leses eller settes.

En property har opptil tre deler:

  • Getter (markert med @property) kjøres når du leser verdien.
  • Setter (markert med @egenskapsnavn.setter) kjøres når du setter en ny verdi.
  • Deleter (markert med @egenskapsnavn.deleter) kjøres når du sletter egenskapen med del.

Getteren er den du bruker oftest. Setteren legger du til når du trenger validering. Deleteren brukes sjelden, men er nyttig hvis du trenger opprydding når en egenskap fjernes.

Slik lager du en property med getter

Først lagrer du den faktiske verdien i en "privat" egenskap med understrek foran. Deretter definerer du en metode med @property-dekoratøren som returnerer verdien:

  • self._armor = armor lagrer verdien med understrek (konvensjon for "ikke rør denne direkte").
  • @property over metoden def armor(self): gjør at armor kan leses som en egenskap.
  • Metoden returnerer self._armor.

Nå kan du skrive print(objekt.armor) akkurat som før. Python kaller getter-metoden automatisk og returnerer verdien fra self._armor.

Legg til validering med setter

Den store gevinsten med property kommer med setteren. Si at du har en egenskap armor som skal være mellom 0 og 100. Med en setter kan du avvise ugyldige verdier:

  • @armor.setter over metoden def armor(self, value):
  • Inne i metoden sjekker du om verdien er gyldig: if not (0 <= value <= 100):
  • Ugyldig verdi gir en ValueError med en tydelig feilmelding.
  • Gyldig verdi lagres med self._armor = value.

Valideringen kjøres hver gang noen prøver å sette verdien, også i __init__. Bruker du self.armor = armor (uten understrek) i konstruktøren, går verdien gjennom setteren og blir validert med en gang. Det betyr at du aldri kan opprette et objekt med ugyldig data.

Understrek-konvensjonen i Python

Python har ingen ekte private egenskaper slik som Java eller C#. En enkelt understrek foran navnet (_armor) er bare en konvensjon som sier "denne er ment for intern bruk". Ingen ting hindrer deg i å skrive objekt._armor = -50 direkte.

Dobbel understrek (__armor) trigger navnmangling, der Python endrer navnet internt for å gjøre det vanskeligere å nå utenfra. Men det er sjelden nødvendig. Enkelt understrek pluss @property er den foretrukne tilnærmingen i Python-verdenen. Det gir kontroll uten å gjøre koden unødvendig kompleks.

Når bør du bruke property?

Ikke pakk inn alle egenskaper i properties bare fordi du kan. Bruk property når du har et konkret behov:

  • Validering: Verdien må holde seg innenfor et gyldig område.
  • Beregning: Egenskapen utledes fra andre verdier. En sirkel kan ha en property for omkrets som beregnes fra radius automatisk.
  • Logging eller varsling: Du vil vite når en verdi endres.
  • Bakoverkompatibilitet: Du startet med en vanlig egenskap, men trenger nå logikk rundt den. Med property kan du legge til logikk uten at eksisterende kode bryter.

Det siste punktet er en av de store fordelene med property i Python. Du kan starte enkelt med direkte tilgang, og oppgradere til property senere uten å endre koden som bruker klassen. I mange andre språk må du planlegge for getters og setters fra starten av.

Property og dictionaries

En vanlig feil er å bruke en dictionary i stedet for en klasse med properties. Dictionaries er fleksible, men gir ingen kontroll. Enhver nøkkel kan inneholde hva som helst. Med en klasse og properties definerer du tydelig hvilke egenskaper som finnes, hvilke verdier de kan ha, og hvordan de beregnes. Bruk dictionaries for løst strukturert data og klasser for data med faste regler.

Neste steg

Nå som du forstår property i Python, er det naturlig å se på de forskjellige typene metoder en klasse kan ha. Artikkelen om statiske metoder og klassemetoder forklarer forskjellen mellom instansmetoder, @classmethod og @staticmethod. For å forstå hvordan klasser bygger på hverandre, viser artikkelen om arv i Python deg hvordan du gjenbruker kode mellom klasser. Pythons offisielle dokumentasjon for property dekker alle detaljer og kanttilfeller.

Denne artikkelen bygger på kurset Python – objektorientert programmering på Utdannet.no. I kurset jobber du med egenskaper, property-dekoratører og innkapsling gjennom praktiske eksempler, og du får oppgaver der du bygger klasser med validering fra bunnen av.