{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "Chyby v Pythonu můžeme rozlišit na *syntaktické chyby* a *chyby za běhu* (*run-time*). Syntaktické chyby jsou způsobeny např. nespárovanými závorkami, špatným odsazením apod. Program se syntaktickými chybami nelze vůbec spustit. Častější jsou run-time chyby, které vznikají nesprávným použitím nějaké funkce, chybějícími daty apod. Jelikož je Python interpretovaný jazyk, většina chyb se ukáže až za běhu, na rozdíl od kompilovaných jazyků, kde se mnoho chyb objeví při kompilaci.\n", "" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Výjimky\n", "\n", "Výjimka (*exception*) je vyhozena ve chvíli, kdy dojde k chybě. Pokud tuto výjimku nezachytíme (viz dále), běh programu se přeruší. Např. dělení nulou skončí výjimkou `ZeroDivisionError`:" ] }, { "cell_type": "code", "metadata": { "collapsed": false, "jupyter": { "outputs_hidden": false }, "ExecuteTime": { "end_time": "2024-04-17T17:48:46.895385Z", "start_time": "2024-04-17T17:48:46.806845Z" } }, "source": [ "1/0" ], "outputs": [ { "ename": "ZeroDivisionError", "evalue": "division by zero", "output_type": "error", "traceback": [ "\u001B[0;31m---------------------------------------------------------------------------\u001B[0m", "\u001B[0;31mZeroDivisionError\u001B[0m Traceback (most recent call last)", "Cell \u001B[0;32mIn[1], line 1\u001B[0m\n\u001B[0;32m----> 1\u001B[0m \u001B[38;5;241;43m1\u001B[39;49m\u001B[38;5;241;43m/\u001B[39;49m\u001B[38;5;241;43m0\u001B[39;49m\n", "\u001B[0;31mZeroDivisionError\u001B[0m: division by zero" ] } ], "execution_count": 1 }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Chytáme výjimky\n", "Pokud nechceme, aby běh programu skončil ve chvíli výjimky, můžeme použít `try` - `except` blok. Ten funguje tak, že rizikovou část kód umístíme do `try` bloku, do `except` bloku pak umístíme instrukce pro případ chyby (výjimky)." ] }, { "cell_type": "code", "metadata": { "collapsed": false, "jupyter": { "outputs_hidden": false }, "ExecuteTime": { "end_time": "2024-04-17T17:48:49.865976Z", "start_time": "2024-04-17T17:48:49.863207Z" } }, "source": [ "try:\n", " 1/0\n", "except:\n", " print(\"nulou se nedělí!\")" ], "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "nulou se nedělí!\n" ] } ], "execution_count": 2 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Takto použitý `except` odchytí všechny výjimky. To není obvykle dobrá praktika, je lepší odchytávat pouze určité výjimky (takové, které očekáváme, že mohou nastat). Pro odchycení dělení nulou by to vypadalo asi takto:" ] }, { "cell_type": "code", "metadata": { "collapsed": false, "jupyter": { "outputs_hidden": false }, "ExecuteTime": { "end_time": "2024-04-17T17:48:51.600393Z", "start_time": "2024-04-17T17:48:51.596835Z" } }, "source": [ "try:\n", " 1/0\n", "# do proměnné e se uloží vyhozená výjimka\n", "except ZeroDivisionError as e:\n", " print(\"nulou se nedělí!\")\n", " print(e)" ], "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "nulou se nedělí!\n", "division by zero\n" ] } ], "execution_count": 3 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Kompletní try-except blok může ještě obsahovat `else` a `finally` bloky, viz [dokumentace](http://docs.python.org/2/reference/compound_stmts.html#try). `finally` se hodí zejména pro \"úklid\", např. zavření souboru apod." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Vyhazujeme výjimky\n", "Výjimku můžeme samozřejmě vyhodit i v našem kódu pomocí klíčového slova `raise`. Pokud bychom chtěli např. kontrolovat vstup nějaké funkce, uděláme to takto:" ] }, { "cell_type": "code", "metadata": { "collapsed": false, "jupyter": { "outputs_hidden": false }, "ExecuteTime": { "end_time": "2024-04-17T17:48:53.531311Z", "start_time": "2024-04-17T17:48:53.526805Z" } }, "source": [ "def fact(n):\n", " \"\"\"Spočítá faktoriál\n", " \"\"\"\n", " from math import factorial\n", " try:\n", " # zkusíme převést n na číslo\n", " n = float(n)\n", " except ValueError as e:\n", " raise ValueError(\"{} není číslo\".format(n))\n", " # je n celé číslo >= 0\n", " if not n.is_integer() or n < 0:\n", " raise ValueError(\"{} není celé číslo >= 0\".format(n))\n", " else:\n", " n = int(n)\n", " return factorial(n)\n", "# jednodychý test\n", "n = 4\n", "print('{}! = {}'.format(n, fact(n)))" ], "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "4! = 24\n" ] } ], "execution_count": 4 }, { "cell_type": "code", "metadata": { "collapsed": false, "jupyter": { "outputs_hidden": false }, "ExecuteTime": { "end_time": "2024-04-17T17:48:54.384226Z", "start_time": "2024-04-17T17:48:54.380910Z" } }, "source": [ "# teď zkusíme, jestli fungují naše výjimky\n", "for n in (4.0, \"0\", 3.2, -1):\n", " try:\n", " print('{}! = {}'.format(n, fact(n)))\n", " # Exception odchytí v podstatě jakoukoli výjimku, ostatní výjimky totiž od ní dědí\n", " except Exception as e:\n", " print(e)" ], "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "4.0! = 24\n", "0! = 1\n", "3.2 není celé číslo >= 0\n", "-1.0 není celé číslo >= 0\n" ] } ], "execution_count": 5 }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Traceback\n", "\n", "Pomocí modulu traceback si můžeme nechat vypsat podrobnější informace jak k vyjímce došlo:" ] }, { "cell_type": "code", "metadata": { "collapsed": false, "jupyter": { "outputs_hidden": false }, "ExecuteTime": { "end_time": "2024-04-17T17:48:55.554291Z", "start_time": "2024-04-17T17:48:55.550902Z" } }, "source": [ "import traceback, sys\n", "\n", "try:\n", " fact(1.1)\n", "except Exception:\n", " traceback.print_exc(file=sys.stdout)" ], "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Traceback (most recent call last):\n", " File \"/tmp/ipykernel_900090/36834011.py\", line 4, in \n", " fact(1.1)\n", " File \"/tmp/ipykernel_900090/3537662117.py\", line 12, in fact\n", " raise ValueError(\"{} není celé číslo >= 0\".format(n))\n", "ValueError: 1.1 není celé číslo >= 0\n" ] } ], "execution_count": 6 }, { "cell_type": "code", "metadata": { "ExecuteTime": { "end_time": "2024-04-17T17:48:56.310411Z", "start_time": "2024-04-17T17:48:56.307222Z" } }, "source": [ "try:\n", " pass\n", " # raise ValueError(\"chyba\")\n", "except ValueError:\n", " print(\"Tato chyba jo ok\")" ], "outputs": [], "execution_count": 7 } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.11.4" } }, "nbformat": 4, "nbformat_minor": 4 }