4. diel - Hracia kocka v Pythone - Prekrývanie metód a random
V minulej lekcii, Hracia kocka v Pythone - Zapuzdrenie a konštruktor, sme začali vytvárať prvý poriadny objekt, bola ním hracia kocka.
V tomto tutoriáli objektovo orientovaného programovania v Pythone budeme pokračovať v tvorbe našej objektovej hracej kocky. Začneme s metódou pre hod. Vysvetlíme si na nej bližšie vnútorný import a potom dôkladne preskúmame princípy prekrývania metód.
Náhodné čísla
Začneme tým, že v triede RollingDie
definujeme ďalšiu
metódu. Nazveme ju roll()
. Metóda nám vráti náhodné číslo
od jednej do počtu stien a nebude mať žiadny parameter. Náhodné číslo
získame za pomoci modulu random
. Modul si naimportujeme
vnútorne ako privátny (použijeme jedno
podtržítko) a použijeme metódu randint()
:
def roll(self): """ Rolls a die and returns a number from 1 to the sides count. """ import random as _random return _random.randint(1, self._sides_count)
Použitie jedného podčiarkovníka pred názvom importovaného modulu (alebo akejkoľvek inej premennej) je - nám už známou - konvenciou v Pythone, ktorá signalizuje, že táto premenná by mala byť považovaná za privátnu a nemala by byť priamo pristupovaná mimo triedy alebo modul.
Vnútorný import
Výraz "vnútorný import" sa vzťahuje na prax importovania modulu priamo vo vnútri funkcie alebo metódy, namiesto toho, aby bol importovaný na začiatku súboru. V niektorých prípadoch to príde vhod, najmä ak:
- modul potrebujeme len v určitých špecifických situáciách,
- import modulu je nákladný na pamäť a čas a nechceme, aby spomaľoval štart aplikácie.
Je dôležité si uvedomiť, že importovanie modulu v Pythone je relatívne nákladná operácia. Avšak iba prvýkrát, kedy je modul importovaný. Ďalšie pokusy o jeho importovanie sú už veľmi rýchle, pretože Python použije už načítanú verziu modulu z pamäte. Inými slovami, pri importovaní modulov sa Python pozrie, či bol už modul importovaný. Ak áno, Python ho znova neimportuje. Preto sa prvý riadok v metóde vykoná len raz. Importy na začiatku súboru, ako sme zvyknutí, sú takmer za všetkých okolností jednoduchším a lepším riešením. Tento koncept teda berte len ako ukážku možností jazyka.
Nadmerné používanie vnútorných importov kód komplikuje a znižuje jeho čitateľnosť. Dobrou praxou je teda používať ich uvážene a len v situáciách, keď prinášajú skutočné výhody.
Prekrývanie metódy
__str__()
Kocka je takmer hotová. Ukážme si teraz ešte jednu užitočnú metódu,
ktorú budeme hojne používať aj vo väčšine našich ďalších objektov.
Reč je o metóde __str__()
. Túto metódu obsahuje
každý objekt, teda aj teraz naša kocka. Metóda je určená
na to, aby vrátila tzv. textovú reprezentáciu inštancie.
Hodí sa vo všetkých prípadoch, keď si inštanciu potrebujeme vypísať
alebo s ňou pracovať ako s textom. Túto metódu majú napr. aj čísla. V
Pythone funguje implicitná konverzia. Akonáhle teda budeme
chcieť do konzoly vypísať číslo alebo ktorýkoľvek iný objekt, Python na
ňom zavolá metódu __str__()
a vypíše jej výstup. Ak si
robíme vlastnú triedu, mali by sme zvážiť, či sa nám takáto metóda
hodí. Nikdy by sme si nemali robiť vlastnú metódu, napr. niečo ako
print()
, keď už máme v Pythone pripravenú cestu, ako toto
riešiť. Pri kocke nemá __str__()
vyšší zmysel, ale u
bojovníka bude určite vracať jeho meno. My si ju ku kocke aj tak pridáme.
Bude vypisovať, že sa jedná o kocku a vráti aj počet stien. Najprv si
vypíšme do konzoly našu inštanciu kocky:
print(sixSided)
Do konzoly sa vypíše iba cesta k našej triede:
Object output:
<__main__.RollingDie object at 0x00000228043EE090>
Hoci je metóda už definovaná a poskytuje nám určitý výstup, chceme o
našej kocke získať podrobnejšie informácie. Najlepšie také, o ktorých
sami rozhodneme, že je vhodné ich zobraziť. To docielime tým, že vstavanú
metódu __str__()
jednoducho definujeme sami znova a tým ju
prekryjeme:
class RollingDie:
"""
Class representing a die for a board game.
"""
def __init__(self,sides_count=6):
self._sides_count = sides_count
def get_sides_count(self):
"""
Returns the number of sides the die has.
"""
return self._sides_count
def roll(self):
"""
Rolls a die and returns a number from 1 to the sides count.
"""
import random as _random
return _random.randint(1, self._sides_count)
def __str__(self):
"""
Returns a textual representation of our die.
"""
return str(f"A rolling die with {self._sides_count} sides.")
sixSided = RollingDie()
tenSided = RollingDie(10) # or we can write RollingDie(sides_count=10)
print(sixSided)
print(tenSided)
V konzole uvidíme:
Overriding the __str__() method:
A rolling die with 6 sides.
A rolling die with 10 sides.
Ešte si naše kocky vyskúšame. Skúsime si v programe s našimi dvoma kockami v cykloch hádzať a pozrieme sa, či fungujú tak, ako sa očakáva. Upravíme koniec súboru:
class RollingDie:
"""
Class representing a die for a board game.
"""
def __init__(self,sides_count=6):
self._sides_count = sides_count
def get_sides_count(self):
"""
Returns the number of sides the die has.
"""
return self._sides_count
def roll(self):
"""
Rolls a die and returns a number from 1 to the sides count.
"""
import random as _random
return _random.randint(1, self._sides_count)
def __str__(self):
"""
Returns a textual representation of our die.
"""
return str(f"A rolling die with {self._sides_count} sides.")
# Creates the dice
sixSided = RollingDie()
tenSided = RollingDie(10)
# Rolls the 6-sided die
print(sixSided)
for _ in range(6):
print(sixSided.roll(), end=" ")
# Rolls the 10-sided die
print("\n", tenSided, sep=" ")
for _ in range(10):
print(tenSided.roll(), end=" ")
Za for
nasleduje podtržítko. Divné, že? V
kontexte slučky for
sa jednoduché podtržítko _
používa ako dočasná premenná, keď nás skutočná hodnota v každom
priechode slučkou nezaujíma. Je to konvenčný spôsob, ako naznačiť, že
hodnota tejto premennej nebude v danom kontexte využitá.
Výstup môže vyzerať nejako takto:
Konzolová aplikácia
A rolling die with 6 sides.
1 6 4 5 5 4
A rolling die with 10 sides.
5 7 3 2 5 10 7 8 3 9
Máme hotovú celkom peknú a nastaviteľnú triedu, ktorá reprezentuje hraciu kocku. Bude sa nám hodiť v našej aréne, ale k dispozícii ju máme na využitie aj kdekoľvek inde. Vidíme, ako OOP umožňuje znovu používať komponenty.
V nasledujúcej lekcii, Zapuzdrenie atribútov podrobne v Pythone, sa budeme podrobnejšie venovať práci s privátnymi atribútmi a ich zapuzdreniu.
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é 0x (952 B)
Aplikácia je vrátane zdrojových kódov v jazyku Python