Jak Python loví štěnice
Chyby neboli bugs (štěnice) jsou v každém programu (téměř). Naučíme se je chytat za běhu pomocí nástroje zvaného debugger ("odstraňovač štěnic"). Navíc si ukážeme, jaké jsou výhody dynamického interpretovaného jazyka, jakým je Python.
Pdb -- základní debugger¶
Pdb je základní debugger pro Python. Základní použití je vložit break pointu do vašeho kódu pomocí set_trace
.
# definice fact
def fact(nn):
"""Spočítá faktoriál
"""
from math import factorial
try:
# zkusíme převést n na číslo
nn = float(nn)
except ValueError as e:
raise ValueError("{} není číslo".format(nn))
# je n celé číslo >= 0
if not nn.is_integer() or nn < 0:
raise ValueError("{} není celé číslo >= 0".format(nn))
return factorial(nn)
# nová funkce s break pointem
def fact_b(nn):
from pdb import set_trace
# tade se běh programu zastaví a objeví se pdb rozhraní
set_trace()
r = fact(nn)
return r
Tady vidíme, jak vypadá interace s pdb. Všímejte si řádků (Pdb) a příkazů do nich zadaných: help
, where
, step
, continue
. To jsou příkazy pro samotný debugger. Kromě toho ale můžeme zadávat i příkazy Pythonu, jako např. dir()
. Toto je velice důležité! V debuggeru máme k dispozici celý Python, všechny jeho funkce atd.
fact_b(4)
Dokonce můžeme za běhu měnit proměnné! Podívejte se, jak jsme do nn uložili 10 a že výsledek tomu odpovídá.
fact_b(4)
IPython debugger¶
Lze asi očekávat, že existují i další možnosti chytání štěnic. Podívejme se, co nabízí náš dobrý známý IPython.
%debug
¶
%debug
(případně %%debug
pro celou buňku) spustí příkaz v debug módu, který se spustí, ještě než se začne cokoli provádět. V ipdb např. funguje doplňování pomocí tabelátoru (to ovšem nefunguje v notebooku), jinak je ale téměř totožný s pdb.
%debug fact(1)
%pdb¶
Pomocí %pdb on
zapneme automatické vyvolání ipdb ve chvíli vyhození výjimky. To je pochopitelně velice užitečné, protože můžeme začít debugovat právě ve chvíli, kdy nastala chyba. Navíc máme k dispozici veškerý kontext (obsah paměti, historii volání (stack trace) apod.).
%pdb on
fact(4.1)
Break pointy jinak¶
Někdy (často) není praktické nastavovat break pointy pomocí set_trace
. (i)pdb nám umožňují nastavit break pointy pomocí čísla řádku (v libovolném souboru) nebo jména funkce. Případně můžeme přidat ještě podmínku.
Pro ukázku definujeme funkci, která vrací (nn!)^2. Spustíme jí v debug módu a umístíme break point do funkce fact pomocí break fact
.
def fact2(nn):
r = fact(nn)**2
return r
%debug fact2(4)
IPython embed¶
Toto není přísně řečeno debugování, ale má to hodně společného. IPython umožňuje spustit přímou interakci s aktuálním kontextem pomocí funkce embed
, případně embed_kernel
. Na rozdíl od pdb se ale změny nepropagují zpět do spuštěcího kontextu, takže jakékoli změny se po ukončení ztratí. Více v dokumentaci.
Další možnosti¶
- Vylepšení pdb: python3-trepan.
- Vynikající je debugger v PyCharm nebo ve VS Code.
- pudb je "grafický" debugger v textovém režimu.
- Většina vývojových prostředí nějakým způsobem umožňuje pustit debugger.
Komentáře
Comments powered by Disqus