14. diel - Magické metódy Pythone - Matematické
V minulej lekcii, Magické metódy v Pythone , sme sa venovali magickým metódam. V tomto Python tutoriále budeme pokračovať s magickými metódami. Tentoraz si ukážeme špeciálne metódy pre matematické operátory. Na triede Vector si tiež ukážeme ich použitia.
Obyčajné operátormi
Tieto operátory sa volajú štandardne na objektu a, ak ich použijeme takto:
c = a + b
Objekt a je odovzdaný ako parameter self a objekt b ako parameter other.
__add __ (self, other)
Metóda sa zavolá na prvom objekte pri použití operátora
+
:
c = a + b
__sub __ (self, other)
Metóda sa zavolá pri použití operátora odčítanie -
:
c = a - b
__mul __ (self, other)
Metóda sa zavolá pri použití operátora násobenia *
:
c = a * b
__truediv __ (self, other)
Metóda sa zavolá pri použití operátora delení /
:
c = a / b
__floordiv __ (self, other)
Metóda sa zavolá pri použití operátora celočíselné delenia
//
:
c = a // b
__mod __ (self, other)
Metóda sa zavolá pri použití operátora zvyšok po delení - modulo
%
:
c = a % b
__divmod __ (self, other)
Vracia dvojicu (a // b, a% b) pre celé čísla:
c = divmod(a, b)
__pow __ (self, other, modulo)
Metóda sa spustí keď použijeme operátor mocniny **
. Metóda
by mala byť schopná brať aj tretí, nepovinný argument (modulo) - https://docs.python.org/...nctions.html#pow:
c = a ** b
__lshift __ (self, other)
Spustené pri použití operátora pre bitový posun vľavo:
c = a << b
__rshift __ (self, other)
Spustené pri použití operátora pre bitový posun vpravo:
c = a >> b
__and __ (self, other)
Spustené pri použití bitového operátora AND &
:
c = a & b
__xor __ (self, other)
Spustené pri použití bitového operátora XOR ^
(non-ekvivalencie):
c = a ^ b
__or __ (self, other)
Spustené pri použití bitového operátora OR |
:
c = a | b
Prehodenie operátormi
Prehodenie (reversed) operátormi sa zavolajú na druhom objekte, ak nie je poskytnutá ich implementácia na prvom objekte.
napr .:
sth = 1 + my_object
Ak int nepodporuje magickú metódu __add __ (), čo pravdepodobne nie, je zavolaná metóda __radd __ () na my_object.
Tieto operátory sa volajú štandardne na objekte b, pričom objekt b je parameter self a objekt a je parameter other
__radd__(self, other)
- Sčítanie__rsub__(self, other)
- Odčítanie__rmul__(self, other)
- Násobenie__rtruediv__(self, other)
- Pravé delenie__rfloordiv__(self, other)
- Celočíselné delenie__rmod__(self, other)
- Zvyšok po delení - modulo__rdivmod__(self, other)
- Vracia dvojicu (a // b, a% b) pre celé čísla.__rpow__(self, other, modulo)
- Mocnina. Metóda by mala byť schopná brať aj tretí, nepovinný argument (modulo).
Funkcia pow (): https://docs.python.org/...nctions.html#pow
__rlshift__(self, other)
- Bitový posun vľavo__rrshift__(self, other)
- Bitový posun vpravo__rand__(self, other)
- Logická funkcia AND__rxor__(self, other)
- Logická funkcia XOR (non-ekvivalencie)__ror__(self, other)
- Logická funkcia OR
Operátormi in place
Tieto operátory umožňujú skrátenú notáciu (na mieste). Parametre metód sú self a other, ale vracia modifikovaný self. Ak niektorá metóda neexistuje, Python sa ju pokúsi emulovať s využitím definovaných metód.
Príklad:
my_object += 1
Python zavolá metódu __iadd __ (). V prípade neúspechu zavolá metódu __add __ () týmto spôsobom:
temp = my_object + 1 # zavolá __add__() my_object = temp
__iadd__(self, other)
- Sčítanie__isub__(self, other)
- Odčítanie__imul__(self, other)
- Násobenie__itruediv__(self, other)
- Pravé delenie__ifloordiv__(self, other)
- Celočíselné delenie__imod__(self, other)
- Zvyšok po delení - modulo__ipow__(self, other, modulo)
- Mocnina. Metóda by mala byť schopná brať aj tretí, nepovinný argument (modulo).__ilshift__(self, other)
- Bitový posun vľavo__irshift__(self, other)
- Bitový posun vpravo__iand__(self, other)
- Logická funkcia AND__ixor__(self, other)
- Logická funkcia XOR (non-ekvivalencie)__ior__(self, other)
- Logická funkcia OR
Ďalšie magické metódy
__neg __ (self)
unárne mínus
-a
__pos __ (self)
unárne plus
+a
__abs __ (self)
Absolútna hodnota, implementuje správania pre funkciu abs ()
abs(a)
__invert __ (self)
unárne inverzie
~a
__complex __ (self)
Implementácia správania pre funkciu complex ()
complex(a)
__int __ (self)
Implementácia správania pre funkciu int ()
int(a)
__float __ (self)
Implementácia správania pre funkciu float ()
float(a)
__round __ (self, n)
Implementácia správania pre funkciu round ()
round(a)
__index __ (self)
Python túto metódu používa pri konverzii numerických typov na int, napríklad pri orezávanie alebo na použitie vstavaných funkcií bin (), hex () a oct (). Táto metóda by mala vracať rovnaký výsledok ako magická metóda __int __ (). A navyše by mala vracať celé číslo (int).
Ukážka niektorých metód
Vytvorme si jednoduchú triedu Vector
, uchovávajúce zložky
x
a y
. Na triede si skúsime implementovať niektoré
zo spomínaných magických metód:
class Vector: def __init__(self, x, y): self.x = float(x) self.y = float(y) def __str__(self): return "({0.x}, {0.y})".format(self) ...
Začiatok je pravdepodobne jasný. V metóde __str __ () získavame zo self atribúty x a y.
def __add__(self, other): if isinstance(other, Vector): return Vector(self.x+other.x, self.y+other.y) elif issubclass(type(other), Sequence): if len(other) == 2: return Vector(self.x+other[0], self.y+other[1]) raise NotImplemented
Najprv porovnáme, či je druhý objekt tiež vektor. Ak áno, vrátime súčet x-ových a y-ových zložiek ako nový vektor.
Ďalšia vetvenia je už zložitejšie. Za pomoci vstavané funkcie
issubclass () kontrolujeme, či je trieda druhého objektu podtriedou Sequence z
modulu collections.abc
. Vďaka tomu môžeme na objekte použiť
funkciu ľan () a získať z objektu prvý a druhý prvok. A to bez obáv, že
by to daný objekt nepodporoval. Ak obe vetvy zlyhajú a nič nevráti, vyvolá
sa výnimka NotImplemented
.
def __mul__(self, other): if issubclass(type(other), Real): return Vector(self.x * other, self.y * other) raise NotImplemented
Tu kontrolujeme, či je other
podtriedou triedy Real (reálne
číslo) z modulu numbers. Preto môžeme vektor vynásobiť inte alebo floatom
a vyhnúť sa zbytočnému vetvenia a kontrolovanie typov objektu.
Uvedené triedy z modulov numbers a collections.abc sú v skutočnosti abstraktné bázovej triedy, teda triedy, u ktorých sa "zaväzujeme" dodržať určité rozhranie objektov, ak je zdedíme. O tom ale zase až v budúcej lekcii, Statika v Pythone druhýkrát - Statické a triedne metódy .
V budúcej lekcii, Statika v Pythone druhýkrát - Statické a triedne metódy , dokončíme tému statiky. Preberieme statické a triedne metódy.