11.5 Polimorfisms un dunder metodes

Tavs šīs stundas izaicinājums: Izprast polimorfismu un Python speciālās ("dunder") metodes objektu pielāgošanai.

SR 2.4.18. Lieto OOP pamatus SR 2.4.11. Standartizētas bibliotēkas un API

Teorija: Polimorfisms un dunder (__metode__)

Polimorfisms = daudzas formas. Dažādas klases ar to pašu metodes nosaukumu, bet atšķirīgu uzvedību.

class Varonis:
    def runa(self): print("Varonis runā vispārīgi.")

class Burvis(Varonis):
    def runa(self): print("Magicāli vārdi!")

class Bruninieks(Varonis):
    def runa(self): print("Par godu un karaļa zemi!")

# Polimorfisms — vienots interfeiss, dažāda uzvedība
for v in [Varonis(), Burvis(), Bruninieks()]:
    v.runa()

Dunder metodes (double underscore) ir iebūvētie āķi, kas ļauj klasei darboties ar Python operatoriem un funkcijām:

MetodeAktivizē
__str__str(o) un print(o)
__repr__repr(o), REPL izvade
__eq__o1 == o2
__lt__, __gt__<, > (sortēšana)
__add__o1 + o2
__len__len(o)
__contains__x in o

1. uzdevums: Polimorfisms praksē

Vairāku klašu kopīga metode.

Izpildes soļi:

  1. Izveido bāzes klasi Ienaidnieks ar metodi uzbrukt(self, merkis), kas izvada vispārīgu ziņojumu.
  2. Izveido Goblins, Pukis, Skelets — katrs pārraksta uzbrukt() ar savu stilu.
  3. Izveido sarakstu ienaidnieki = [Goblins(), Pukis(), Skelets()].
  4. Cikls: for e in ienaidnieki: e.uzbrukt(varonis) — viens kods, dažāda uzvedība.

2. uzdevums: __str__ un __repr__

Padari savus objektus skaisti izvadāmus.

Izpildes soļi:

  1. Klasei Varonis pievieno def __str__(self): return f"{self.vards} ({self.hp} HP)".
  2. Pievieno def __repr__(self): return f"Varonis({self.vards!r}, hp={self.hp})".
  3. Izvada: print(varonis) izsauc __str__, ievada Python REPL — __repr__.
  4. Izvada sarakstu: print([v1, v2]) — kura metode tiek izsaukta?

3. uzdevums: __eq__ un __lt__ — sortēšana

Padari objektus salīdzināmus.

Izpildes soļi:

  1. Pievieno def __eq__(self, other): return self.hp == other.hp.
  2. Pievieno def __lt__(self, other): return self.hp < other.hp.
  3. Izveido sarakstu ar 5 varoņiem — sakārto: sorted(saraksts).
  4. Atrod minimumu: min(saraksts).
  5. Pievieno __hash__ = None, ja klase ir maināma (lai netiktu lietota kā vārdnīcas atslēga).

Papildus uzdevums: __add__ un operatoru pārslogošana

Pielāgo + operatoru savai klasei.

Izpildes soļi:

  1. Izveido klasi Vektors ar x, y atribūtiem.
  2. Pievieno def __add__(self, other): return Vektors(self.x + other.x, self.y + other.y).
  3. Izveido divus vektorus un saskaiti tos ar + operatoru.
  4. Pievieno __sub__ un __mul__.

Biežākās kļūdas

Koda piemērs

class Varonis:
    def __init__(self, vards, hp): self.vards = vards; self.hp = hp
    def __str__(self): return f"{self.vards} ({self.hp} HP)"
    def __repr__(self): return f"Varonis({self.vards!r}, hp={self.hp})"
    def __lt__(self, other): return self.hp < other.hp
    def __eq__(self, other): return self.hp == other.hp

varoni = [Varonis("Anna", 100), Varonis("Jānis", 80), Varonis("Eva", 120)]
for v in sorted(varoni):
    print(v)
Jānis (80 HP)
Anna (100 HP)
Eva (120 HP)
⬅ Iepriekšējā stunda Nākamā stunda ➡