13. diel - Statika v Pythone druhýkrát - Statické a triedne metódy
V tomto tutoriále objektovo orientovaného programovania v Pythone budeme pokračovať v práci so statikou. Vysvetlíme si statické a triedne metódy.
Statické metódy
Statické metódy sa podobne ako triedne premenné volajú na triede. Ide najmä o pomocné metódy, ktoré potrebujeme často používať a neoplatí sa nám kvôli nim tvoriť inštanciu.
Pozrime sa opäť na reálny príklad. Pri registrácii nového
používateľa potrebujeme poznať minimálnu dĺžku hesla ešte pred jeho
vytvorením. Bolo by tiež dobré, keby sme mohli pred jeho vytvorením aj heslo
skontrolovať, či má správnu dĺžku, neobsahuje diakritiku, je v ňom aspoň
jedno číslo a podobne. Za týmto účelom si vytvoríme pomocnú
statickú metódu zvaliduj_heslo()
, ktorú si zavoláme na
triede Uzivatel
:
Pozor! Kvôli
tomu, že je metóda zvaliduj_heslo()
statická, nemôžeme v nej
pristupovať k žiadnym inštančným premenným. Tieto premenné totiž
neexistujú v kontexte triedy, ale inštancie. Pýtať sa napríklad na
jmeno
by v našej metóde nemalo zmysel!
Dekorátor @staticmethod
Zhrňme si znalosti, ktoré sme zatiaľ získali a povedzme si niekoľko
detailov k použitému dekorátoru. Dekorátor @staticmethod
sa v
Pythone používa na označenie metódy triedy, ktorá nevyžaduje referenciu na
konkrétnu inštanciu triedy (self
) ani na samotnú triedu
(cls
- viac si povieme za chvíľu). Inými slovami, statická
metóda pracuje nezávisle od inštancií triedy a jej
správanie sa nemení na základe stavu inštancie alebo
triedy.
Dekorátory v Pythone predstavujú spôsob, ako modifikovať alebo rozširovať funkčnosť funkcií alebo tried bez nutnosti meniť ich pôvodný kód. Okrem užívateľsky definovaných dekorátorov Python ponúka aj rad vstavaných dekorátorov, ktoré uľahčujú bežné úlohy v objektovo orientovanom programovaní, napríklad prácu s triednymi alebo statickými metódami. O dekorátoroch si podrobne povieme neskôr v kurze.
Hlavné výhody použitia @staticmethod
:
- zrejmosť - keď vidíme v kóde dekorátor
@staticmethod
, je jasné, že táto metóda nezávisí od stavu inštancie ani triedy, - výkon - pretože
@staticmethod
nevyžaduje odovzdanieself
alebocls
, býva volanie tejto metódy o niečo rýchlejšie.
@staticmethod
používame
Statickú metódu teda použijeme, keď:
- metóda nevyžaduje prístup k žiadnym atribútom alebo metódam triedy,
- metóda nevyžaduje zmenu v triede alebo jej inštanciách,
- máme logickú funkciu, ktorá by sa vhodne hodila do triedy (napr. kvôli organizácii kódu), ale nevyužíva konkrétne vlastnosti triedy.
Geometrie
, ktorá bude
obsahovať niekoľko statických metód spojených s geometrickými výpočtami:
Vo výstupe konzoly uvidíme:
Prečo vôbec @staticmethod
používame
V Pythone je síce technicky možné definovať metódy vo vnútri triedy bez
použitia @staticmethod
dekorátora, ale na jeho použitie máme
niekoľko pádnych argumentov:
- zrejmosť - Už sme si povedali, že dekorátor
@staticmethod
jasne hovorí, že metóda nemá prístup k inštančným ani triednym atribútom/metódam. Keď tento dekorátor iní vývojári vidia, okamžite vedia, čo od tej metódy môžu očakávať. - organizácie a design - Použitie
@staticmethod
nám pomáha pri organizácii kódu. - rozšíriteľnosť - Ak sa neskôr rozhodneme, že chceme pridať nejaké triedne alebo inštančné atribúty/metódy, ktoré by mohli interagovať s našimi statickými metódami, je oveľa jednoduchšie a čistejšie mať už štruktúru, ktorá rozlišuje medzi statickými a ne-statickými metódami.
- odovzdanie
self
acls
- Keď definujeme metódu v triede bez@staticmethod
, prvý argument je automaticky považovaný za referenciu na inštanciu (self
) alebo na triedu (cls
), ak je to triedna metóda (o tých si povieme za chvíľu). Ľahko tak narazíme na problémy s nesprávnym počtom argumentov pri volaní funkcie:
Dekorátor
@staticmethod
teda umožňuje metódu volať ako cez triedu, tak
cez inštanciu bez toho, aby bolo nutné dodávať self
:
Skrátka, aj keď je možné
vytvárať "statické" metódy v Pythone bez použitia
@staticmethod
, dekorátor nám poskytuje oveľa väčšiu
flexibilitu, čitateľnosť a
robustnosť pri práci s triedami.
Utility (helper) triedy
Keď sa zamyslíme nad tým, čo sme si doteraz povedali, vyplýva nám jedno
zaujímavé zistenie. Python nám umožňuje vytvárať akési kontajnery
(obvykle súvisiacich) metód, združených v jednej triede. Takéto triede sa
hovorí utility trieda (alebo tiež helper
trieda). Ich hlavnou funkciou je usporiadať súbor súvisiacich
funkcií do jednej logickej jednotky, čo nám pomáha k lepšej organizácii
kódu a lepšej čitateľnosti. Za príklad nám poslúži naša trieda
Geometrie
, avšak bez dekorátora @staticmethod
as
upraveným názvom GeometrieUtilities
popisujúcim jej účel:
Týmto spôsobom si teda
vieme vytvoriť kontajner metód, ktoré sú na prvý pohľad statické a treba
len pamätať na to, že taká utility trieda neslúži na vytváranie
inštancií, ale skôr ako sada nástrojov, alebo priamo knižnica. Hoci
neexistuje pevná konvencia pre pomenovanie tohto typu tried, odporúčame v
názve zohľadniť ich podstatu. Tak, ako sme urobili v našom príklade s
triedou GeometrieUtilities
. Mnoho štandardných knižníc v
Pythone obsahuje moduly, ktoré v podstate fungujú ako utility triedy, pretože
poskytujú sady funkcií či metód bez potreby vytvárať inštancie.
Pozor! Utility triedy neinštancujeme. Volanie metódy utility triedy z jej inštancie spôsobí chybu.
Triedne metódy
Python obsahuje okrem statických aj triedne metódy. A tu
sa konečne dostávame k onomu tajomnému cls
Prvý parameter triednej metódy
vždy obsahuje odkaz na triedu a podľa konvencií sa pomenováva
cls
. Za pomoci tohto parametra potom voláme triedne premenné,
podobne ako so self
. Triedne metódy pracujú s triednymi
premennými a nie s inštančnými premennými. Označujeme ich pomocou
dekorátora @classmethod
. Triedne metódy sa hodia v tom
prípade, že budeme triedu dediť a chceme mať v potomkovi inú hodnotu
triedneho atribútu. Inak je lepšie použiť statickú metódu.
Najlepšie bude, keď si ukážeme príklad:
V konzole uvidíme:
V našom príklade voláme
triednu metódu vrat_hodnotu()
na potomkovi. Metóda nám vráti
hodnotu atribútu hodnota
z triedy Potomek
,
nie z triedy Rodic
. Ale pozor,
staticka_metoda()
nemá žiadny prístup k triednym atribútom,
takže nezáleží na tom, či je volaná z rodiča či potomka –
vždy bude vracať rovnaký výstup.
Rozdiely medzi triednymi a statickými metódami
Pozrime sa stručný prehľad rozdielov medzi triednymi a statickými metódami:
1. Dekorátor:
- Triedna metóda používa dekorátor
@classmethod
. - Statická metóda používa dekorátor
@staticmethod
.
- Triedna metóda - prvým parametrom je vždy odkaz na triedu, obvykle
pomenovaný
cls
. - Statická metóda - nemá žiadny špeciálny prvý parameter. Chová sa ako bežná funkcia, ktorá je iba definovaná vo vnútri triedy.
- Triedna metóda - pokiaľ je trieda dedená, triedna metóda v potomkoch bude pracovať s triednymi atribútmi daného potomka,
- Statická metóda - je nezávislá od dedenia. Či je volaná z rodičovskej triedy alebo z potomka, chová sa vždy rovnako.
- Triedna metóda - je užitočná, keď potrebujeme pracovať s triednymi atribútmi alebo keď chceme, aby metóda bola upraviteľná v dedených triedach.
- Statická metóda - je vhodná, keď potrebujeme vykonať nejakú operáciu, ktorá súvisí s triedou, ale nevyžaduje si prístup k jej atribútom. Je to v podstate funkcia, ktorá nesúvisí s konkrétnou inštanciou triedy.
Uzivatel
, ktorá nás sprevádza od
začiatku témy statiky:
V príklade máme metódy:
zvaliduj_heslo()
- statická metóda a je možné ju volať aj cez inštanciu, ale jej logika závisí iba na konkrétnej triedeUzivatel
, nie na tom, aká inštancia (bežný užívateľ alebo VIP) ju volá.informace_o_hesle()
- triedna metóda v triedeVIPUzivatel
a keď ju voláme cez inštanciu, vracia informácie špecifické pre triedu tej inštancie (VIPUzivatel
v našom prípade).je_heslo_validni()
- metóda inštancie, ktorá využíva statickú metóduzvaliduj_heslo()
. Demonštruje, ako metóda inštancie dokáže využívať statické aj triedne metódy.
V nasledujúcom cvičení, Riešené úlohy k 12.-15. lekciu OOP v Pythone, si precvičíme nadobudnuté skúsenosti z predchádzajúcich lekcií.
Mal si s čímkoľvek problém? Stiahni si vzorovú aplikáciu nižšie a porovnaj ju so svojím projektom, chybu tak ľahko nájdeš.
Stiahnuť
Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkami
Stiahnuté 20x (1.08 kB)
Aplikácia je vrátane zdrojových kódov v jazyku Python