Vytvoř si vlastní třídu pro celá čísla tak, aby tato nová třída měla všechny vlastnosti a schopnosti běžných celých čísel v Pythonu (objekty bude možné sčítat, odečítat, porovnávat atp.) a navíc měla metodu pro rozpoznání, zda je číslo v objektu sudé nebo liché jménem je_sude()
, která bude vracet True
nebo False
.
Nejsmazší je dědit přímo z třídy int
a přidat jen jednu vlastní metodu.
In [1]:
class CeleCislo(int):
def je_sude(self):
return self % 2 == 0
In [2]:
x = CeleCislo(5)
x.je_sude()
Out[2]:
In [3]:
y = CeleCislo(6)
y.je_sude()
Out[3]:
Metoda __repr__
vrací řetězec, který reprezentuje objekt například při výpisu v interaktivní konzoli. Tato metoda může vracet libovolný řetězec.
In [4]:
class CeleCislo(int):
def je_sude(self):
return self % 2 == 0
def __repr__(self):
return "<Cele cislo {}>".format(self)
In [5]:
y = 5
y
Out[5]:
In [6]:
x = CeleCislo(5)
x
Out[6]:
Kompatibilita zůstala díky dědění zachována.
In [7]:
a = 5
b = CeleCislo(7)
In [8]:
a + b
Out[8]:
In [9]:
a - b
Out[9]:
In [10]:
a < b
Out[10]:
In [11]:
b >= a
Out[11]:
Pro domácí projekt to nebylo potřeba, ale pojďme si zkusit vytvořit vlastní třídu s implementovanými metodami pro využití operátorů v Pythonu.
In [12]:
class Pizza:
def __init__(self, jmeno, ingredience):
self.jmeno = jmeno
self.ingredience = ingredience
def __repr__(self):
return "<Pizza '{}' na které je '{}'".format(self.jmeno, self.ingredience)
In [13]:
p = Pizza("salámová", ["sýr", "paprikáš", "suchý salám"])
p
Out[13]:
Pro matematické operátory existují speciální metody, jejichž názvy odpovídají použitým operátorům/operacím.
In [14]:
class Pizza:
def __init__(self, jmeno, ingredience):
self.jmeno = jmeno
self.ingredience = ingredience
def __repr__(self):
return "<Pizza '{}' na které je '{}'".format(self.jmeno, self.ingredience)
def __add__(self, other):
jmeno = self.jmeno + " " + other.jmeno
ingredience = self.ingredience + other.ingredience
return Pizza(jmeno, ingredience)
In [15]:
p1 = Pizza("salámová", ["sýr", "paprikáš", "suchý salám"])
p2 = Pizza("hawai", ["máslo", "ananas"])
In [16]:
p1 + p2
Out[16]:
In [17]:
p2 - p1
Pro porovnání máme také speciální metody - pro každý operátor jednu.
In [18]:
class Pizza:
def __init__(self, jmeno, ingredience):
self.jmeno = jmeno
self.ingredience = ingredience
def __repr__(self):
return "<Pizza '{}' na které je '{}'".format(self.jmeno, self.ingredience)
def __add__(self, other):
jmeno = self.jmeno + " " + other.jmeno
ingredience = self.ingredience + other.ingredience
return Pizza(jmeno, ingredience)
def __lt__(self, other):
return len(self.ingredience) < len(other.ingredience)
In [19]:
p1 = Pizza("salámová", ["sýr", "paprikáš", "suchý salám"])
p2 = Pizza("hawai", ["máslo", "ananas"])
p3 = Pizza("pro chude", ["eidam"])
p4 = p1 + p2
In [20]:
p3 < p1
Out[20]:
In [21]:
p3 > p1
Out[21]:
In [22]:
p4 < p2
Out[22]:
Řazení je jen speciální případ porovnávání, kdy se mezi sebou porovnají všechny prvky a podle výsledku jednotlivých porovnání se seřadí. K tomu nám stačí mít implementovánu alespoň metodu __lt__
.
In [23]:
pizzy = [p1, p2, p3, p4]
pizzy
Out[23]:
In [24]:
sorted(pizzy)
Out[24]:
Seznam všech speciálních metod a jejich chování najdeš klasicky v dokumentaci Pythonu.