En av Pythons mindre kjente, men verdifulle funksjoner er muligheten til å implementere magiske metoder på objekter. Ved hjelp av magiske metoder kan vi skrive renere kode som er intuitiv og lett å forstå.
Med magiske metoder kan vi lage grensesnitt for å samhandle med objekter på en måte som føles mer pytonisk. Denne artikkelen vil introdusere deg til magiske metoder, diskutere beste praksis for å lage dem og utforske de vanlige magiske metodene du vil møte.
Innholdsfortegnelse
Hva er magiske metoder?
Magiske metoder er Python-metoder som definerer hvordan Python-objekter oppfører seg når vanlige operasjoner utføres på dem. Disse metodene er tydelig definert med doble understrekinger før og etter metodenavnet.
Som et resultat blir de ofte kalt dunder-metoder, som i dobbel understrek. En vanlig dunder-metode du kanskje allerede har møtt er metoden __init__() som brukes til å definere klassekonstruktører.
Vanligvis er ikke dunder-metoder ment å bli kalt direkte i koden din; snarere vil de bli oppringt av tolken mens programmet kjører.
Hvorfor er magiske metoder nyttige?
Magiske metoder er et nyttig konsept i objektorientert programmering i Python. Ved å bruke dem spesifiserer du oppførselen til dine egendefinerte datatyper når de brukes med vanlige, innebygde operasjoner. Disse operasjonene inkluderer:
Aritmetiske operasjoner
🟢 Sammenligningsoperasjoner
Livssyklusoperasjoner
🟢 Representasjonsoperasjoner
Den følgende delen vil diskutere hvordan man implementerer magiske metoder som definerer hvordan applikasjonen oppfører seg når den brukes i alle kategoriene ovenfor.
Hvordan definere magiske metoder
Som nevnt tidligere spesifiserer magiske metoder oppførselen til objekter. Som sådan er de definert som en del av objektets klasse. Fordi de er en del av objektklassen, tar de inn som det første argumentet selv som er en referanse til selve objektet.
De kan ta inn ytterligere argumenter avhengig av hvordan de vil bli oppringt av tolken. De er også tydelig definert med to understrekinger før og etter navnene deres.
Gjennomføring
Mye av det vi har diskutert så langt virker teoretisk og abstrakt. I denne delen skal vi implementere en enkel rektangelklasse.
Denne klassen vil ha lengde- og breddeegenskaper. Ved å bruke __init__-metoden kan du spesifisere disse egenskapene ved instansiering. I tillegg vil du kunne sammenligne forskjellige rektangler for å se om de er lik, mindre eller større enn en annen ved å bruke ==, < og > operatorene. Til slutt bør rektangelet være i stand til å gi en meningsfull strengrepresentasjon.
Sette opp kodemiljøet
For å følge med på denne gjennomgangen, trenger du et Python-løpemiljø. Du kan bruke en lokal, eller du kan bruke den elektroniske tipsbilk.net Python-kompilatoren.
Opprette rektangelklassen
Først, la oss starte med å definere rektangelklassen.
class Rectangle: pass
Opprette konstruktørmetoden
La oss deretter lage vår første magiske metode, klassekonstruktørmetoden. Denne metoden vil ta inn høyden og bredden og lagre dem som attributter på klasseforekomsten.
class Rectangle: def __init__(self, height, width): self.height = height self.width = width
Opprette en magisk metode for strengrepresentasjon
Deretter ønsker vi å lage en metode som lar klassen vår generere en menneskelesbar streng for å representere objektet. Denne metoden kalles hver gang vi kaller str()-funksjonen som sender inn en forekomst av Rectangle-klassen som et argument. Denne metoden vil også bli kalt når du kaller opp funksjoner som forventer et strengargument, for eksempel utskriftsfunksjonen.
class Rectangle: def __init__(self, height, width): self.height = height self.width = width def __str__(self): return f'Rectangle({self.height}, {self.width})'
Metoden __str__() skal returnere en streng som du ønsker skal representere objektet. I dette tilfellet returnerer vi en streng av formatet Rectangle(
Opprette magiske metoder for sammenligningsoperasjoner
Deretter ønsker vi å lage sammenligningsoperatorer for lik til, mindre enn og større enn operasjoner. Dette kalles operatøroverbelastning. For å lage disse bruker vi de magiske metodene __eq__, __lt__ og __gt__ henholdsvis. Disse metodene vil returnere en boolsk verdi etter å ha sammenlignet arealene til rektanglene.
class Rectangle: def __init__(self, height, width): self.height = height self.width = width def __str__(self): return f'Rectangle({self.height}, {self.width})' def __eq__(self, other): """ Checking for equality """ return self.height * self.width == other.height * other.width def __lt__(self, other): """ Checking if the rectangle is less than the other one """ return self.height * self.width < other.height * other.width def __gt__(self, other): """ Checking if the rectage is greater than the other one """ return self.height * self.width > other.height * other.width
Som du kan se, tar disse metodene inn to parametere. Den første er det gjeldende rektangelet, og den andre er den andre verdien det sammenlignes med. Denne verdien kan være en annen rektangelforekomst eller en hvilken som helst annen verdi. Logikken for hvordan sammenligningen og betingelsene som sammenligningen vil returnere til er helt opp til deg.
Vanlige magiske metoder
I denne neste delen vil vi diskutere de vanlige magiske metodene du vil møte og bruke.
#1. Aritmetiske operasjoner
Aritmetiske magiske metoder kalles når en forekomst av klassen din er plassert på venstre side av et aritmetisk tegn. Metoden kalles med to argumenter, den første er en referanse til instansen. Den andre verdien er objektet til høyre for skiltet. Metodene og tegnene er som følger:
NameMethodSignDescriptionAddition__add__+Implementerer tillegg. Subtraksjon__sub__–Implementerer subtraksjon.Multiplication__mul__*Implementerer multiplikasjonDivision__div__/Implementerer divisjon.Etageinndeling__floordiv__//Implementerer etasjedeling.
#2. Sammenligningsoperasjoner
I likhet med de aritmetiske magiske metodene, kalles disse metodene når en forekomst av klassen de er definert for er plassert til venstre for sammenligningsoperatoren. Også, som aritmetiske magiske metoder, kalles de med to parametere; den første er en referanse til forekomsten av objektet. Den andre er en referanse til verdien på høyre side av skiltet.
NameMethodSignDescriptionLess than__lt__
#3. Livssyklusoperasjoner
Disse metodene vil bli kalt som svar på de forskjellige livssyklusmetodene til et objekt, for eksempel å bli instansiert eller slettet. Konstruktøren __init__ faller inn under denne kategorien. De vanlige metodene i denne kategorien er oppført i tabellen nedenfor:
NameMethodDescriptionConstructor__init__Denne metoden kalles når et objekt i klassen den er definert for slettes. Den kan brukes til å utføre oppryddingshandlinger som å lukke alle filer den hadde åpnet.Deletion__del__Denne metoden kalles når et objekt i klassen den er definert for slettes. Den kan brukes til å utføre oppryddingshandlinger som å lukke alle filer den hadde åpnet. New__new__ __new__-metoden kalles først når et objekt av den angitte klassen instansieres. Denne metoden kalles før konstruktøren og tar inn klassen så vel som eventuelle tilleggsargumenter. Den returnerer en forekomst av klassen. For det meste er det ikke så nyttig, men det er dekket i detalj her.
#4. Representasjonsoperasjoner
NameMethodDescriptionStr__str__Returnerer en menneskelesbar strengrepresentasjon av objektet. Denne metoden kalles når du kaller str()-funksjonen, og sender en forekomst av klassen som et argument. Det kalles også når du sender i instansen til funksjonene print() og format(). Det er ment å gi en streng som er forståelig av sluttbrukeren av applikasjonen.Repr__repr__Returnerer en strengrepresentasjon av objektet som brukes av utvikleren. Ideelt sett bør strengen som returneres være informasjonsrik, slik at du kan konstruere en identisk forekomst av objektet fra bare strengen.
Beste praksis for å lage magiske metoder
Magiske metoder er utrolige og vil forenkle koden din. Det er imidlertid viktig å ha følgende ting i bakhodet når du bruker dem.
- Bruk dem sparsomt – Å implementere for mange magiske metoder i klassene dine gjør koden vanskelig å forstå. Begrens deg til å implementere bare de essensielle.
- Sørg for at du forstår ytelsesimplikasjonene av metoder som __setatrr__ og __getattr__ før du bruker dem.
- Dokumenter oppførselen til de magiske metodene dine, slik at andre utviklere kan vite nøyaktig hva de gjør. Dette gjør det lettere for dem å bruke dem og feilsøke når det er nødvendig.
Siste ord
I denne artikkelen introduserte jeg magiske metoder som en måte å lage klasser på som kan brukes med innebygde operasjoner. Jeg diskuterte også hvordan de er definert og gikk gjennom et eksempel på en klasse som magiske metoder implementerte. Deretter nevnte jeg de forskjellige metodene du sannsynligvis kommer til å bruke og trenger før du deler noen beste fremgangsmåter du bør huske på.
Deretter vil du kanskje lære hvordan du implementerer Counter-klassen i Python.