OOP spetsiaalsed meetodid¶
Pythoni klass võib spetsiaalsete meetoditega implementeerida operatsioone nagu erinevad aritmeetilised tehted objektide vahel, objekti initsialiseerimine ja palju muud. See on Pythoni viis operaatoreid üle laadida, et defineerida vajalikku käitumist objektide vahel.
Vaatame kõige populaarsemaid spetsiaalseid meetodeid.
__init__
Klassi initsialiseerimismeetod ehk konstruktor. Objekti loomisel jõuavad argumendid sellesse meetodisse. See on hea koht objekti muutujate salvestamiseks.
class Dog:
def __init__(self, name):
self.name = name
__str__
Seda meetodit kutsub str(object)
ehk see on objekti ilus sõneline representatsioon.
Kui meil see puudub, siis vaikimisi olemasolev objekti sõne väljaprint pole väga informatiivne.
class Dog:
def __init__(self, name):
self.name = name
d = Dog('Leo')
print(d) # <__main__.Dog object at 0x101d665c0>
# Now let's add the __str__ method
class Dog:
def __init__(self, name):
self.name = name
def __str__(self):
return self.name
d = Dog('Leo')
print(d) # Leo
__repr__
Seda meetodit kutsub repr(object)
. See annab sarnaselt __str__
meetodile objekti representatsiooni, aga
see on mõeldud rohkem masinloetavuseks. Kui printida listi objektidest, siis listi enda __str__
kutsub iga listi objekti __repr__
meetodit.
Hea stackoverflow postitus erinevustest: https://stackoverflow.com/questions/1436703/difference-between-str-and-repr
Objektide võrdluseks on meetodid __eq__
, __ne__
, __lt__
, __gt__
, __le__
, __ge__
.
Vaatame näidet, kus kirjutatakse üle võrdluse meetodid kaartide vahel.
Kui üks baas võrdluse meetod on üle kirjutatud, siis saavad teised seda ära kasutada.
Võrdlusmeetodite ülekirjutamine võimaldab näiteks kaarte sorteerida.
class Card:
def __init__(self, suit, rank):
self.suit = suit
self.rank = rank
def __str__(self):
return f'{self.rank} of {self.suit}'
def __repr__(self):
return self.__str__()
def __eq__(self, other):
return self.suit == other.suit and self.rank == other.rank
def __gt__(self, other):
if self.suit == other.suit:
return self.rank > other.rank
return self.suit > other.suit
def __ne__(self, other):
return not self == other
def __le__(self, other):
return not self > other
def __lt__(self, other):
return not (self > other or self == other)
def __ge__(self, other):
return not self < other
cards = [
Card('Spades', 7),
Card('Hearts', 9),
Card('Spades', 8),
Card('Hearts', 7),
Card('Spades', 6),
]
print(sorted(cards))
# [7 of Hearts, 9 of Hearts, 6 of Spades, 7 of Spades, 8 of Spades]
print(sorted(cards, reverse=True))
# [8 of Spades, 7 of Spades, 6 of Spades, 9 of Hearts, 7 of Hearts]
Lisaks on palju erinevate konteineritega seotud meetodeid __len__
, __getitem__
, __setitem__
, __delitem__
,
__iter__
, __reversed__
, __contains__
, __missing__
.
Nõuanne
Vaata põhjaliku nimekirja meetoditest koos lühikirjeldustega https://rszalski.github.io/magicmethods/
Näiteks __missing__
meetodit saab kasutada sõnastiku alamklassides ja seda kutsutakse juhul, kui üritatakse
sõnastikust võtta elementi võtmega, mida pole.
Lihtne näide, kus oma loodud sõnastik tagastab puuduva võtme korral None
ega viska erindit KeyError
.
class MyDict(dict):
def __missing__(self, key):
return None
d = MyDict()
d['age'] = 5
print(d['name']) # None'
Rohkem lugemist
Põhjalik nimekiri näidete ja selgitusega: https://rszalski.github.io/magicmethods/
Ametlik dokumentatsioon: https://docs.python.org/3/reference/datamodel.html#special-method-names