Vad är magiska metoder i Python och hur man använder dem

En av Pythons mindre kända men ändå värdefulla funktioner är förmågan att implementera magiska metoder på objekt. Med hjälp av magiska metoder kan vi skriva renare kod som är intuitiv och lätt att förstå.

Med magiska metoder kan vi skapa gränssnitt för att interagera med objekt på ett sätt som känns mer pytoniskt. Den här artikeln kommer att introducera dig till magiska metoder, diskutera bästa praxis för att skapa dem och utforska de vanliga magiska metoderna du kommer att stöta på.

Vad är magiska metoder?

Magiska metoder är Python-metoder som definierar hur Python-objekt beter sig när vanliga operationer utförs på dem. Dessa metoder är tydligt definierade med dubbla understreck före och efter metodnamnet.

Som ett resultat kallas de vanligtvis för dundermetoder, som i dubbel understreck. En vanlig dundermetod som du kanske redan har stött på är metoden __init__() som används för att definiera klasskonstruktörer.

Vanligtvis är dunder-metoder inte avsedda att anropas direkt i din kod; snarare kommer de att anropas av tolken när programmet körs.

Varför är magiska metoder användbara?

Magiska metoder är ett användbart koncept i objektorienterad programmering i Python. Med hjälp av dem anger du beteendet för dina anpassade datatyper när de används med vanliga, inbyggda operationer. Dessa operationer inkluderar:

Aritmetiska operationer

🟢 Jämförelseoperationer

Livscykeloperationer

🟢 Representationsverksamhet

Följande avsnitt kommer att diskutera hur man implementerar magiska metoder som definierar hur applikationen beter sig när den används i alla ovanstående kategorier.

Hur man definierar magiska metoder

Som nämnts tidigare specificerar magiska metoder objektens beteende. Som sådana definieras de som en del av objektets klass. Eftersom de är en del av objektklassen tar de in som första argument jag som är en referens till själva objektet.

De kan ta in ytterligare argument beroende på hur de kommer att bli uppringda av tolken. De är också tydligt definierade med två understreck före och efter deras namn.

Genomförande

Mycket av det vi har diskuterat hittills verkar teoretiskt och abstrakt. I det här avsnittet kommer vi att implementera en enkel rektangelklass.

Denna klass kommer att ha egenskaper för längd och bredd. Med metoden __init__ kan du ange dessa egenskaper vid instansiering. Dessutom kommer du att kunna jämföra olika rektanglar för att se om de är lika, mindre eller större än en annan med hjälp av operatorerna ==, < och >. Slutligen bör rektangeln kunna ge en meningsfull strängrepresentation.

Konfigurera kodningsmiljön

För att följa denna genomgång behöver du en Python-runtime-miljö. Du kan använda en lokal, eller så kan du använda online-adminvista.com Python-kompilatorn.

Skapa rektangelklassen

Först, låt oss börja med att definiera klassen Rectangle.

class Rectangle:
    pass

Skapa konstruktörsmetoden

Låt oss sedan skapa vår första magiska metod, klasskonstruktormetoden. Denna metod tar in höjden och bredden och lagrar dem som attribut i klassinstansen.

class Rectangle:
    def __init__(self, height, width):
        self.height = height
        self.width = width

Skapa en magisk metod för strängrepresentation

Därefter vill vi skapa en metod som gör att vår klass kan generera en läsbar sträng för att representera objektet. Denna metod kommer att anropas när vi anropar funktionen str() som skickar en instans av klassen Rectangle som ett argument. Den här metoden kommer också att anropas när du anropar funktioner som förväntar sig ett strängargument, till exempel utskriftsfunktionen.

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__() bör returnera en sträng som du skulle vilja representera objektet. I det här fallet returnerar vi en sträng av formatet Rectangle(, ) där höjd och bredd är rektangelns lagrade dimensioner.

Skapa magiska metoder för jämförelseoperationer

Därefter vill vi skapa jämförelseoperatorer för lika med, mindre än och större än operationer. Detta kallas för operatörsöverbelastning. För att skapa dessa använder vi de magiska metoderna __eq__, __lt__ respektive __gt__. Dessa metoder kommer att returnera ett booleskt värde efter jämförelse av rektanglarnas ytor.

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 dessa metoder in två parametrar. Den första är den aktuella rektangeln och den andra är det andra värdet som den jämförs med. Detta värde kan vara en annan Rectangle-instans eller något annat värde. Logiken för hur jämförelsen och villkoren under vilka jämförelsen kommer att vara sann är helt upp till dig.

Vanliga magiska metoder

I det här nästa avsnittet kommer vi att diskutera de vanliga magiska metoderna du kommer att stöta på och använda.

#1. Aritmetiska operationer

Aritmetiska magiska metoder kallas när en instans av din klass placeras till vänster om ett aritmetiskt tecken. Metoden kommer att anropas med två argument, det första är en referens till instansen. Det andra värdet är objektet till höger om tecknet. Metoderna och tecknen är följande:

NameMethodSignDescriptionAddition__add__+Implementerar tillägg. Subtraktion__sub__–Implementerar subtraktion.Multiplication__mul__*Implementerar multiplikationDivision__div__/Implements division. Floor division__floordiv__//Implements floor division.

#2. Jämförelseoperationer

Liksom de aritmetiska magiska metoderna anropas dessa metoder när en instans av klassen de är definierade för placeras till vänster om jämförelseoperatorn. Liksom aritmetiska magiska metoder kallas de också med två parametrar; den första är en referens till instansen av objektet. Den andra är en referens till värdet på skyltens högra sida.

NameMethodSignDescriptionLess than__lt__Implementerar större än jämförelseEqual to__eq__==Implementerar lika med comparisonLess than eller lika med__le__>=Implementerar mindre än eller lika med jämförelseStörre änmp__lika med< eller=I jämförelse

#3. Livscykelverksamhet

Dessa metoder kommer att anropas som svar på de olika livscykelmetoderna för ett objekt, till exempel att instansieras eller tas bort. Konstruktören __init__ faller under denna kategori. De vanligaste metoderna i denna kategori listas i tabellen nedan:

NameMethodDescriptionConstructor__init__Denna metod anropas när ett objekt i klassen det är definierat för tas bort. Den kan användas för att utföra rensningsåtgärder som att stänga alla filer som den hade öppnat.Deletion__del__Denna metod anropas när ett objekt i klassen den är definierad för raderas. Den kan användas för att utföra rensningsåtgärder som att stänga alla filer som den hade öppnat. New__new__metoden __new__ anropas först när ett objekt av den angivna klassen instansieras. Denna metod anropas före konstruktorn och tar in klassen såväl som eventuella ytterligare argument. Den returnerar en instans av klassen. För det mesta är det inte så användbart, men det behandlas i detalj här.

#4. Representationsverksamhet

NameMethodDescriptionStr__str__Returnerar en läsbar strängrepresentation av objektet. Denna metod anropas när du anropar funktionen str() och skickar en instans av klassen som ett argument. Det kallas också när du skickar i instansen till funktionerna print() och format(). Det är tänkt att tillhandahålla en sträng som är förståelig för slutanvändaren av applikationen. Repr__repr__Returnerar en strängrepresentation av objektet som används av utvecklaren. Helst bör den returnerade strängen vara informationsrik så att du kan konstruera en identisk instans av objektet från bara strängen.

Bästa metoder för att skapa magiska metoder

Magiska metoder är otroliga och kommer att förenkla din kod. Det är dock viktigt att ha följande saker i åtanke när du använder dem.

  • Använd dem sparsamt – Att implementera för många magiska metoder i dina klasser gör din kod svår att förstå. Begränsa dig till att implementera endast de väsentliga.
  • Se till att du förstår prestandaimplikationerna av metoder som __setatrr__ och __getattr__ innan du använder dem.
  • Dokumentera beteendet hos dina magiska metoder så att andra utvecklare kan veta exakt vad de gör. Detta gör det lättare för dem att använda dem och felsöka vid behov.

Slutord

I den här artikeln introducerade jag magiska metoder som ett sätt att göra klasser som kan användas med inbyggda operationer. Jag diskuterade också hur de definieras och gick igenom ett exempel på en klass som magiska metoder implementerade. Därefter nämnde jag de olika metoderna som du sannolikt kommer att använda och behöver innan du delar några bästa praxis att tänka på.

Därefter kanske du vill lära dig hur du implementerar Counter-klassen i Python.