Finjustera beteendet för dina klasser med Pythons flexibla överstyrningsmekanism.

I Python ger klasser ett rent sätt att bunta ihop data och funktionalitet till återanvändbara element. Genom att skapa anpassade klasser kan du modellera verkliga enheter som användare, produkter och anställda.

Python-klasser definierar magiska metoder som du kan anpassa så att du kan forma dina klassers beteende för unika situationer.

Förstå magiska metoder

Föreställ dig magiska metoder, även kallade dunder-metoder, som hemliga besvärjelser eller dolda sånger som Python automatiskt anropar när du utför vissa åtgärder på ett objekt.

Python ger en hel del inbyggt beteende för klasser igenom instans-, statiska- och klassmetoder. Du kan skapa Python-klasser, och anpassa dem ytterligare med hjälp av magiska metoder.

Magiska metoder är instansmetoder i Python som har två understreck (__metod__) före och efter metodnamnet.

Dessa speciella metoder ger instruktioner till Python om hur man hanterar objekt i en klass. Här är några vanliga magiska metoder i Python-klasser:

instagram viewer
  • __gt__: Denna metod kontrollerar om ett objekt är större än ett annat.
  • __i det__: Den här metoden körs när du skapar en instans av en klass, och den är främst för attributinitiering.
  • __str__: Detta returnerar en strängrepresentation av klassen som beskriver objektet.
  • __repr__: Denna metod ger en utdata som låter dig återskapa objektet med hjälp av eval().
  • __len__: När du använder len() funktion på ett objekt denna metod returnerar objektets längd.
  • __eq__: Den här metoden gör det möjligt att jämföra objekt med dubbla lika med (==) operatör.
  • __lt__: Den implementerar mindre än (
  • __Lägg till__: När du använder tillägget (+) operatör på objekt den här metoden körs och utför additionsoperationer.
  • __getitem__: Låter dig hämta objekt från ett objekt med hjälp av indexsyntax, som obj[nyckel].

Implementera magiska metoder

Det bästa sättet att förstå magiska metoder är att använda dem.

Strängrepresentation av ett objekt

Du kan anpassa strängrepresentationen av ett objekt för läsbarhet eller vidare bearbetning.

classPerson:
def__init__(self, name, age):
self.name = name
self.age = age

p1 = Person('John', 25)
print(p1)

Här har du en enkel Person klass med en __i det__ magisk metod för att initiera den. När du skriver ut p1 objekt, använder den standardsträngrepresentationen som tillhandahålls av Python.

För att anpassa strängrepresentationen, definiera __str__ och __repr__ magiska metoder:

classPerson:
def__init__(self, name, age, height):
self.name = name
self.age = age
self.height = height

def__str__(self):
returnf'{self.name} is {self.age} years old'

def__repr__(self):
returnf'{self.name} is {self.age} years old'

p1 = Person('John', 25, 78)
print(p1)

Nu har du en mer läsbar och heltäckande strängrepresentation av p1 objekt:

Längdegenskap för ett objekt

Föreställ dig det när du ringer len() metod för ett personobjekt, vill du ha deras höjd. Implementera __len__ magisk metod för Person klass:

classPerson:
def__init__(self, name, age, height):
self.name = name
self.age = age
self.height = height

def__str__(self):
returnf'{self.name} is {self.age} years old'

def__repr__(self):
returnf'{self.name} is {self.age} years old'

def__len__(self):
return self.height

p2 = Person('Issac', 25, 89)
print(len(p2))

De __len__ magisk metod returnerar höjdattributet för en Person exempel. När du ringer len (p2), kommer det att kalla __len__ magisk metod automatiskt som returnerar höjden på p2 objekt.

Hantering av jämförelser mellan objekt

Om du behöver jämföra objekt i en klass baserat på vissa egenskaper hos klassen. Du kan definiera __eq__ magisk metod och implementera din jämförelselogik.

classPerson:

def__init__(self, name, age, height):
self.name = name
self.age = age
self.height = height

def__str__(self):
returnf'{self.name} is {self.age} years old'

def__repr__(self):
returnf'{self.name} is {self.age} years old'

def__len__(self):
return self.height

def__eq__(self, other):
return self.name == other.name and self.age == other.age

p1 = Person('John', 25, 56)
p2 = Person('John', 25, 61)

print(p1 == p2)

De __eq__ metoden jämför namn och ålder egenskaper hos de två Personens mål för att bestämma jämlikhet.

Det dubbla lika med (==)-operatören använder den här metoden för att kontrollera jämlikhet i stället för att jämföra identiteter. Så två Person instanser är lika om de har matchande namn och åldersattribut. Detta gör att du kan åsidosätta standardbeteendet för jämställdhetskontroll för din anpassade klass.

Genom att implementera dessa magiska metoder kan du definiera anpassat beteende som kommer att stämma överens med Pythons inbyggda funktioner.

Avancerade magiska metoder

Här är några avancerade exempel på hur man använder magiska metoder för att anpassa klasser.

Få klasser att fungera som behållare

Med hjälp av magiska metoder kan du definiera klasser som beter sig som behållare. Du kan använda behållare, som tuplar, för att lagra samlingar av dataelement. De tillhandahåller olika metoder för att manipulera, komma åt och iterera genom de inneslutna elementen.

classPerson:
def__init__(self):
self.data = []

def__len__(self):
return len(self.data)

def__getitem__(self, index):
return self.data[index]

def__setitem__(self, index, value):
self.data[index] = value

def__delitem__(self, index):
del self.data[index]

p1 = Person()
p1.data = [10, 2, 7]
print(len(p1)) # 3

p1[0] = 5
print(p1[0]) # 5

Nu kan ett personobjekt bete sig som en behållare:

Anpassa attributåtkomst

Använda __getattr__ magisk metod kan du anpassa hur attributen för Person klass nås baserat på vissa villkor.

classPerson:
def__getattr__(self, name):
if name == 'age':
return40
else:
raise AttributeError(f'No attribute {name}')

p1 = Person()
print(p1.age) # 40

De __getattr__ metod kommer att köras när du försöker komma åt ett attribut som inte finns direkt i objektet. I det här fallet kontrollerar den om attributnamnet är ålder och ger tillbaka 40.

För alla andra attributnamn väcker det en AttributeError med ett motsvarande meddelande.

Få klasser att bete sig som ringbara

De __ring upp__ metoden låter dig behandla en instans av klassen som ett anropsbart objekt (dvs. en funktion).

classAdder:
def__call__(self, x, y):
return x + y

adder = Adder()
print(adder(2, 3)) # 5

När du skapar en instans av Huggorm och kalla det sedan med argument, __ring upp__ metoden körs och utför tillägget innan resultatet returneras.

Operatör överbelastning

Med hjälp av magiska metoder kan du utföra överbelastning av operatören. Operatörsöverbelastning låter dig definiera anpassade beteenden för inbyggda operatorer när de används med instanser av dina egna klasser. Här är ett vanligt exempel som förklarar operatörens överbelastning.

classVector:
def__init__(self, x, y):
self.x = x
self.y = y

def__add__(self, other):
if isinstance(other, Vector):
new_x = self.x + other.x
new_y = self.y + other.y
return Vector(new_x, new_y)
else:
raise TypeError("Unsupported operand type for +")

def__str__(self):
returnf"({self.x}, {self.y})"

# Creating two Vector instances
v1 = Vector(2, 3)
v2 = Vector(1, 4)

# Adding two Vector instances using the + operator
v3 = v1 + v2

# Printing the result
print(v3) # Output: (3, 7)

Resultatet är en ny vektor:

De Vektor klass definierar __Lägg till__ metod, som körs när du använder + operatorn mellan två instanser av klassen. Metoden lägger till motsvarande komponenter i de två vektorerna och returnerar en ny Vektor exempel med resultatet.

Här har du sett grundläggande magiska metoder som du kan implementera för att anpassa ditt klassbeteende. Python har många fler magiska metoder som erbjuder mer flexibilitet när du skapar klasser. Referera till officiell dokumentation för en komplett lista.

Objektorienterad programmering i Python

Magiska metoder i Python ger kraftfulla sätt att anpassa och förbättra klassernas beteende. Magiska metoder går ihop med konceptet objektorienterad programmering (OOP) i Python. Så det är viktigt att förstå begreppet OOP när man försöker använda magiska metoder.