{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Обработка исключений" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Исключения (exceptions) - ещё один тип данных в `Python`. \n", "Исключения необходимы для того, чтобы сообщать программисту об ошибках." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Список основных встроенных исключений:\n", "\n", "* Exception – то, на чем фактически строятся все остальные ошибки;\n", "\n", "* AttributeError – возникает, когда ссылка атрибута или присвоение не могут быть выполнены;\n", "\n", "* IOError – возникает в том случае, когда операция I/O (такая как оператор вывода, встроенная функция open() или метод объекта-файла) не может быть выполнена, по связанной с I/O причине: «файл не найден», «диск заполнен» и т.п.;\n", "\n", "* ImportError – возникает, когда оператор import не может найти определение модуля, или когда оператор не может найти имя файла, который должен быть импортирован;\n", "\n", "* IndexError – возникает, когда индекс последовательности находится вне допустимого диапазона;\n", "\n", "* KeyError – возникает, когда ключ сопоставления (dictionary key) не найден в наборе существующих ключей;\n", "* KeyboardInterrupt – возникает, когда пользователь нажимает клавишу прерывания(обычно Delete или Ctrl+C);\n", "* NameError – возникает, когда локальное или глобальное имя не найдено;\n", "* OSError – возникает, когда функция получает связанную с системой ошибку;\n", "* SyntaxError – возникает, когда синтаксическая ошибка встречается синтаксическим анализатором;\n", "* TypeError – возникает, когда операция или функция применяется к объекту несоответствующего типа. Связанное значение представляет собой строку, в которой приводятся подробные сведения о несоответствии типов;\n", "* ValueError – возникает, когда встроенная операция или функция получают аргумент, тип которого правильный, но неправильно значение, и ситуация не может быть описана более точно, как при возникновении IndexError;\n", "* ZeroDivisionError – возникает, когда второй аргумент операции division или modulo равен нулю." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Самый простейший пример исключения - деление на ноль:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "100/0" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Для обработки исключений используется конструкция `try - except`.\n", "\n", "В блоке `try` мы выполняем инструкцию, которая может породить исключение, а в блоке `except` мы перехватываем ошибки. При этом перехватываются как само исключение, так и его потомки. \n", "\n", "Первый пример применения этой конструкции:" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0\n" ] } ], "source": [ "try:\n", " k = 1 / 0\n", "except ZeroDivisionError:\n", " k = 0\n", "print(k)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### \"Голое\" исключение" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Также возможна инструкция except без аргументов, будут найдены вообще все исключения. Причина, по которой так делать не рекомендуется, заключается в том, что вы не узнаете, что именно за исключение вы выловите. " ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Произошла ошибка!\n" ] } ], "source": [ "try:\n", " 1 / 0\n", "except:\n", " print(\"Произошла ошибка!\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "\n", "Вы также можете выявить несколько ошибок за раз при помощи одного оператора. Для этого существует несколько различных способов.\n", "\n", "Самый стандартный способ выявить несколько исключений:" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Этого ключа нет в словаре!\n" ] } ], "source": [ "my_dict = {\"a\":1, \"b\":2, \"c\":3}\n", " \n", "try:\n", " value = my_dict[\"d\"]\n", "except IndexError:\n", " print(\"Такого индекса не существует!\")\n", "except KeyError:\n", " print(\"Этого ключа нет в словаре!\")\n", "except:\n", " print(\"Произошла еще одна ошибка!\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Второй способ выявления нескольких исключений: " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "try:\n", " value = my_dict[\"d\"]\n", "except (IndexError, KeyError):\n", " print(\"Произошла ошибка IndexError или KeyError!\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "В данном примере мы помещаем ошибки, которые мы хотим выявить, внутри круглых скобок. Проблема данного метода в том, что трудно сказать какая именно ошибка произошла, так что предыдущий пример рекомендован больше чем этот. Зачастую, когда происходит ошибка, вам нужно уведомить пользователя, при помощи сообщения." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Блок *finally* в Python\n", "\n", "После последнего блока except можно добавить блок `finally`. Он исполняет инструкции при любых условиях." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "try:\n", " value = my_dict[\"d\"]\n", "except KeyError:\n", " print(\"Этого ключа нет в словаре!\")\n", "finally:\n", " print(\"Выражение выполнено!\")" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "try:\n", " print(1/0)\n", "except ValueError:\n", " print(\"Это ошибка значения\")\n", "finally:\n", " print(\"Это будет напечатано в любом случае.\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Пункт *else* в `try/except`" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Он работает только в том случае, если в вашем коде нет ошибки. Рассмотрим пример:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "my_dict = {\"a\":1, \"b\":2, \"c\":3}\n", " \n", "try:\n", " value = my_dict[\"a\"]\n", "except KeyError:\n", " print(\"Этого ключа нет в словаре!\")\n", "else:\n", " print(\"Никакой ошибки не произошло!\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "В операторе `try/except` мы открываем доступ к существующему ключу. Это работает, так что ошибка `KeyError` не возникает. Так как ошибки нет, `else` работает, и надпись “Никакой ошибки не произошло!” появляется на экране.\n", "\n", "Теперь добавим оператор `finally`:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "try:\n", " value = my_dict[\"a\"]\n", "except KeyError:\n", " print(\"Этого ключа нет в словаре!\")\n", "else:\n", " print(\"Никакой ошибки не произошло!\")\n", "finally:\n", " print(\"Выражение работает!\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Единственное полезное применение оператора `else`, когда вы хотите запустить вторую часть кода, в которой может быть ошибка. Конечно, если ошибка возникает в `else`, то она не будет поймана." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Обработка исключений в цикле. В данном примере у пользователя будут запрашиваться числа до тех пор, пока не будут введены числа неравные нулю или выполнение не будет прервано (обычно Ctrl-C)." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "while True:\n", " a = input(\"Введите число: \")\n", " b = input(\"Введите второе число: \")\n", " try:\n", " result = int(a)/int(b)\n", " except ValueError:\n", " print(\"Поддерживаются только числа\")\n", " except ZeroDivisionError:\n", " print(\"На ноль делить нельзя\")\n", " else:\n", " print(result)\n", " break" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Если же цикл находится внутри обработчика исключений, то его выполнение завершится при первой произошедшей ошибке. В данном примере у пользователя будут запрашиваться числа и будет выводится их частное до тех пор, пока не будут введены некорретные значения." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "try:\n", " while True:\n", " a = input(\"Введите число: \")\n", " b = input(\"Введите второе число: \")\n", " result = int(a)/int(b)\n", " print(result) \n", "except ValueError:\n", " print(\"Поддерживаются только числа\")\n", "except ZeroDivisionError:\n", " print(\"На ноль делить нельзя\") " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "###### Исключение, произошедшее в методе, вызов которого находится в обработчике исключений, так же будет обработано." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def division(x,y):\n", " return int(a)/int(b)\n", " \n", "try:\n", " a = input(\"Введите число: \")\n", " b = input(\"Введите второе число: \")\n", " print(division(a,b))\n", "except ZeroDivisionError:\n", " print(\"На ноль делить нельзя\")" ] } ], "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.7.5" } }, "nbformat": 4, "nbformat_minor": 2 }