16. diel - Typový systém a type hints v Pythone
V predchádzajúcom cvičení, Riešené úlohy k 12.-15. lekciu OOP v Pythone, sme si precvičili získané skúsenosti z predchádzajúcich lekcií.
Hoci je Python dynamicky typizovanom, stále sa jedná o silne typizovanom jazyk, ktorý vyžaduje priradenie typu premennej. Toto sa síce väčšinou odohráva automaticky, ale aj tak sú prípady, kedy sa hodí si typy v Pythone manuálne a explicitne uviesť. Napríklad vďaka uvedeniu typov môže naša IDE lepšie kontrolovať správnosť nášho kódu. Pre väčšie projekty je táto praktika veľmi užitočná.
Samotný Python nami uvedené typy ignoruje a priraďuje si
je vždy sám, nehľadiac na to, čo mu my explicitne uvedieme. Toto uvedenie
teda naozaj slúži iba ako informácia pre nás, popr. pre IDE alebo nástroj mypy
, ktorý typy
overuje.
Základné typy v Pythone a ich použitie
Základné typy v Pythone sú:
int
pre celé číslofloat
pre reálne číslobool
pre hodnotyTrue
/False
str
pre reťazceNone
preNone
Ak chceme explicitne deklarovať typ premennej, použijeme k tomu
dvojtečkový operátor :
:
text: str = "Ahoj světe!"
Teraz je jasne povedané, že text
je typu str
. Tu
by to bolo rovnako spoznať podľa hodnoty "Ahoj světe!"
, Takže
je tu také označenie trochu zbytočné. V programe je ale veľa miest, kde to
už také jasné nie je. Napr. môžeme typovo i parametre funkcií a ich
návratové hodnoty:
def generuj_ahoj(jmeno: str) -> str: return "Ahoj, " + jmeno + "!"
Už spomínanými nástrojmi je v tejto chvíli potom možné skontrolovať, či nám všetko sedí, prípadne vygenerovať k funkciám dokumentáciu vrátane typov.
Ďalšie typy v Pythone
Samozrejme toto nie sú všetky typy, ktoré sa môžu v Pythone objaviť.
Iste sami zvládnete vymenovať mnohé ďalšie - list
,
dict
atď. Že je premenná typu list
môžeme
označiť pomocou:
muj_list: list = [1, 2, 3]
Toto by nám ale nebolo moc užitočné. Síce by sme vedeli, že daná
premenná je list
, ale nevedeli by sme akého typu sú prvky,
ktoré sa v tomto liste nachádzajú.
Knižnica typing
Presne s týmto nám pomôže knižnica
typing
:
from typing import List, Set, Dict, Optional, Callable
Typovanie zoznamov a množín
Prvé dve importované položky nám prídu iste intuitívne, typ prvkov v nich uložených sa určuje pomocou hranatých zátvoriek:
muj_list: List[int] = [1, 2, 3] muj_set: Set[int] = set(muj_list)
Slovníky
Ak chceme typovú slovník, s jedným takým parametrom si nevystačíme. Budeme teda potrebovať parametre dva - prvý pre typ kľúča a druhý pre typ hodnôt:
muj_slovnik: Dict[int, str] = {1: 'jedna', 2: 'dva', 3: 'tri'}
Samozrejme môžeme ako parametre používať aj zložitejšie typy, než len a len tie primitívne:
muj_slovnik2: Dict[int, List[str]] = {1: ['jedna', 'one'], 2: ['dva', 'two'], 3: ['tri', 'three']}
Optional
Kedy sa nám ale môže hodiť typ Optional
?
Optional
v skratke značí to, že daná premenná môže
nadobúdať hodnoty typu prvého parametra alebo None
. To sa nám
hodí napríklad, ak by sme chceli vytvoriť funkciu na delenie a chceli
zabrániť delenie nulou:
def deleni(a: float, b: float) -> Optional[float]: if b == 0: return None # nesmíme dělit nulou return a / b
Callable
Posledný typ, ktorý sme si importovali, sa volá Callable
. Ako
už názov napovedá, jedná sa o typ niečoho, čo sa môže volať, teda
funkcií:
def pridej_jedna(a: int) -> int: return a + 1 operace: Callable = pridej_jedna print(operace(5)) # vypíše 6
Vytváranie vlastných typov
Typy v Pythone môžeme vytvárať tromi spôsobmi:
- typové aliasy
- triedy
- pomenovaný slovník
Typové aliasy
Ak nejaký komplikovaný typ používame často, môžeme si vytvoriť typový alias, ktorý sa vytvorí jednoduchých priradením pôvodného typu do premennej. Napríklad sa nám to môže hodiť pri definícii matíc:
matice: List[List[int]] = [[1, 2], [3, 4]]
môžeme vďaka vytvoreniu typovému aliasu napísať ako
Matrix = List[List[int]] matice: Matrix = [[1, 2], [3, 4]]
Triedy
Každá trieda sa berie aj ako vlastný typ, či už ju importujeme, alebo sami vytvoríme:
class MojeTrida: pass moje_promenna: MojeTrida = MojeTrida() from queue import Queue fronta: Queue = Queue()
Problémom, na ktorý by sme mohli naraziť, by bolo, že by sme chceli využiť typ, ktorý bol deklarovaný až ďalej v súbore (popr. Typ danej triedy samotnej). V čase čítania daného riadku ho teda parser nepozná. Tomu môžeme predísť tak, že namiesto priameho odkazu na danú triedu uzavrieme jej meno do úvodzoviek ako textový reťazec. napr .:
from typing import Optinal, Any class LinkedList: def __init__(self): self.value: Optional[Any] = Noneprvky self.next: Optional["LinkedList"] = None
Typizovanom slovník
Posledným typom vytváranie typov v Pythone, ktorý dnes preberieme, je
vytvorenie typizovaného slovníka (TypedDict
), ktorý sa
prvýkrát objavil v Pythone 3.8. Ide o akúsi abstrakciu nad klasickým
slovníkom, kedy ale explicitne uvedieme, ktoré kľúče s akým typom hodnôt
sa môžu v slovníku nachádzať:
from typing import TypedDict class AdresaDomu(TypedDict): mesto: str ulice: str cislo_domu: int AdresaDomu = TypedDict('AdresaDomu', mesto=str, ulice=str, cislo_domu=int) AdresaDomu = TypedDict('AdresaDomu', {'mesto': str, 'ulice': str, 'cislo_domu': int}) moje_adresa: AdresaDomu = {'mesto': 'Stare Mesto', 'ulice': 'Nova ulice', 'cislo_domu': 52}
Alternatívny systém typovanie
Tento systém, ktorý sme si ukázali, je v Pythone dostupný od verzie 3.5,
takže ak používate Python 3.4 a staršie, nemáme dostupné nič z knižnice
typing
, ani dvojtečkový operátor. Napriek tomu ale môžeme
typové - a to pomocou komentárov. Takže napríklad reťazcovú premennú by
sme deklarovali nasledovne:
muj_text = "Ahoj" # type: str
Tento systém je možné využívať aj v Pythone 3.5 a novším, pričom v niektorých konkrétnych situáciách je to stále jediný možný spôsob typovanie bez toho, aby nám interpreter hlásil časť kódu, ktorú nevie zparsovat.
Ďalšie štúdium
V tejto lekcii sme si ukázali, ako v Pythone používať základné typovanie, čo nám vystačí pre naprostú väčšinu bežných prípadov. Niekoľko posledných verzií Pythone preukázalo, že typovanie je vec, ktorú sa chce jazyk stále viac zaoberať a je preto stále vo vývine. Ak by sme chceli nájsť najaktuálnejšie postupy pri typování, najlepšie bude konzultovať oficiálny dokumentáciu.
V budúcej lekcii, Najčastejšie chyby Python nováčikov - Vieš pomenovať objekty? , si ukážeme najčastejšie chyby začiatočníkov v Pythone ohľadom pomenovania tried, metód a atribútov.