Мир Python: исключения | Python для продвинутых
Зарегистрируйтесь для доступа к 15+ бесплатным курсам по программированию с тренажером
Введение
В этом уроке вы узнаете о важном средстве языка, без которого крупная программа не может обойтись. Речь пойдет об исключениях. Что это такое, как ими пользоваться и как создавать собственные?
Исключительные ситуации или исключения (exceptions) – это ошибки, обнаруженные при исполнении. Например, к чему приведет попытка чтения несуществующего файла? Или если файл был случайно удален пока программа работала? Такие ситуации обрабатываются при помощи исключений.
Если же Python не может понять, как обойти сложившуюся ситуацию, то ему не остается ничего кроме как поднять руки и сообщить, что обнаружил ошибку. В общем, исключения необходимы, чтобы сообщать программисту об ошибках.
Простейший пример исключения — деление на ноль:
>>> 100 / 0 Traceback (most recent call last): File "", line 1, in 100 / 0 ZeroDivisionError: division by zero
В данном случае интерпретатор сообщил нам об исключении ZeroDivisionError – делении на ноль.
Traceback
В большой программе исключения часто возникают внутри. Чтобы упростить программисту понимание ошибки и причины такого поведения Python предлагает Traceback или в сленге – трэйс. Каждое исключение содержит краткую информацию, но при этом полную, информацию о месте появления ошибки. По трэйсу найти и исправить ошибку становится проще.
Рассмотрим такой пример:
Traceback (most recent call last): File "/home/username/Develop/test/app.py", line 862, in _handle return route.call(**args) File "/home/username/Develop/test/app.py", line 1729, in wrapper rv = callback(*a, **ka) File "/home/username/Develop/test/__init__.py", line 76, in wrapper body = callback(*args, **kwargs) File "/home/username/Develop/test/my_app.py", line 16, in index raise Exception('test exception')
В данном примере чётко видно, какой путь исполнения у программы. Смотрим снизу вверх и по шагам понимаем, как же мы докатились до такого исключения.
Рассмотрим какие ещё встречаются комментарии к исключениям:
>>> 2 + '1' Traceback (most recent call last): File "", line 1, in 2 + '1' TypeError: unsupported operand type(s) for +: 'int' and 'str'
В данном примере при попытке сложить целое число и строку мы получаем исключение TypeError. В описании сразу же становится ясно, что же мы не так написали.
>>> int('qwerty') Traceback (most recent call last): File "", line 1, in int('qwerty') ValueError: invalid literal for int() with base 10: 'qwerty'
Приведение строчки к целому числу приводит к исключению ValueError.
В трэйсе этих двух примеров можно прочесть, что в таком-то файле на такой-то строчке есть ошибки.
На этом список встроенных исключений не заканчивается, в следующем разделе рассмотрены основные исключения и причины их возникновения.
Иерархия исключений
Исключение, которое вы не увидите при выполнении кода – это BaseException – базовое исключение, от которого берут начало остальные.
- Системные исключения и ошибки
- Обыкновенные исключения
Если обработку первых лучше не делать (если и делать, то надо четко понимать для чего), то обработку вторых целиком и полностью Python возлагает на плечи программиста.
К системным можно смело отнести:
- SystemExit – исключение, порождаемое функцией sys.exit при выходе из программы.
- KeyboardInterrupt – возникает при прерывании программы пользователем (обычно сочетанием клавиш Ctrl+C).
- GeneratorExit — возникает при вызове метода close объекта generator.
Остальные исключения – это «обыкновенные». Спектр уже готовых исключений велик.
Для Python2 иерархию исключений можно представить так:
Список исключений покрывает большой объем ситуаций и ошибок программиста. Если предупреждения (warning) только просят обратить внимание, то ошибки уже могут остановить исполнение программы.
В Python3 появились новые исключения и иерархия стала такова:
В целом заметно, что при создании Python3 добавлен блок новых исключений. Но даже этих почти 70 исключений не хватает при написании программ на языке Python.
Использование исключений
Мы рассмотрели что такое исключения, какие они бывают и как их анализировать. Но до сих пор явно не рассмотрели такую важную вещь, как их использование.
Начнем с обработки.
Обработка исключений
Давайте рассмотрим случай с делением на 0.
>>> a = 100 >>> b = 0 >>> c = a / b
Данный код приведет к исключению ZeroDivisionError. Чтобы этого не случилось, воспользуемся конструкцией
, например, так:
>>> try: ... a = 100 ... b = 0 ... c = a / b ... except ZeroDivisionError as e: ... print(e) ... division by zero
Если исполнить этот код, то на консоль будет выведена строка «integer division or modulo by zero«. Казалось бы, что толком ничего это нам не дало, ошибка все также есть. Однако в блок except можно поместить обработку.
Например, мы условились, что значение переменной c в случае ошибки деления равно -1. Тогда модифицируем код:
>>> try: ... a = 100 ... b = 0 ... c = a / b ... except ZeroDivisionError as e: ... c = -1 >>> c -1
Перед тем как идти дальше, рассмотрим ещё одну возможность.
Пускай у нас файл с данными в файловой системе, и необходимо его прочитать. В этом случае сразу же всплывают несколько исключительных ситуаций, такие как: нет файла, файл битый, файл пустой (по заданию мы знаем, что в нём данные) и другие.
Используя исключения, можно вот так решить эту задачу:
try: filepath = 'test_file.txt' with open(filepath, 'r') as fio: result = fio.readlines() if not result: raise Exception("File is empty") except IOError as e: result = [] except Exception as e: result = [] print(e)
В данном вымышленном коде новый ход – перехват нескольких видов исключений. Когда исключение брошено, оно сравнивается сверху вниз с каждым типом, пока не найдено совпадение. Если совпадения нет, то исключение пойдет наверх по цепочке исполнения кода.
Если обработка для разных типов исключений одинакова, то уменьшить количество кода становится не проблемой:
try: your_code except (IOError, Exception) as e: print(e)
Вызов исключений
При работе с исключениями программист тратит большую часть времени на обработку, но при этом возникают ситуации, когда исключениями надо и бросать в других.
На сленге программистов «бросить исключение» означает написать код, который при исполнении будет инициировать исключительную ситуацию.
Например, функция, которая решает квадратное уравнение. Вы условились, что корни только вещественные, тогда в случае комплексных корней стоит бросить исключение.
Чтобы бросить исключение необходимо воспользоваться raise
Пример:
raise IOError("текст исключения")
где IOError это класс исключения.
Если при обработке исключения вы желаете пробросить его ещё выше, то следует написать такой код:
try: your_code except Exception as e: raise
Собственные исключения
При написании собственных программ разумное желание добавить выразительности коду, а так же обратить внимание других программистов на особые исключительные ситуации. Для решения этой задачи стоит использовать собственные исключения.
В минимальном исполнении необходимо наследоваться от какого-нибудь класса в иерархии исключений. Например так:
class MyException(Exception): pass
Тогда можно бросить своё исключение:
raise MyException(Exception)
Легко заметить, мы создаем класс, а значит всё, что мы знаем о классах, справедливо и для исключений. Можно завести переменные и делать их обработку.
Как правило, исключения это очень маленькие классы. Они должны выполняться максимально быстро.
Дополнение: Полная форма try..except
Форма try...except
не полная, полной же является try..except..else..finally
.
Применение полной конструкции может заметно упростить код, а также сделать его более безопасным.
Представим, что в программе происходит чтение файла и необходимо убедиться, что объект файла был корректно закрыт и что не возникло никакого исключения. Этого можно достичь с применением блока finally.
Иными словами, finally выполняет блок инструкций в любом случае, было ли исключение, или нет. А инструкция else выполняется в том случае, если исключения не было.
В целом, использование полной формы таково:
try: исполяем какой-то код except Exception as e: обработка исключения else: код, который будет исполнен в случае, когда не возникает исключения finally: код, который гарантированно будет исполнен последним (всегда исполняется)
Выводы
В уроке рассмотрены вопросы связанные с исключениями:
- Что такое исключение
- Какие типы исключений присутствуют в языке
- Как обрабатывать исключения
- Как вызвать исключения
- Как создавать собственные исключения
Остались вопросы? Задайте их в разделе «Обсуждение»
Вам ответят команда поддержки Хекслета или другие студенты.
azureml.interpret.common.exceptions module — Azure Machine Learning Python
Обратная связь
Twitter LinkedIn Facebook Адрес электронной почты
- Ссылка
Определяет пользовательские исключения, создаваемые пакетом azureml-interpret.
Классы
ConflictingRawTransformationsException | Исключение, указывающее на то, что сопоставление признаков и преобразования переданы неправильно. |
DimensionMismatchException | Исключение, указывающее на несовпадение размеров входных данных пользователя и выходных данных модели пользователя. |
DirectoryExistsException | Исключение, указывающее, что такой каталог уже существует. |
ExplanationNotFoundException | Исключение, указывающее, что не удалось найти объяснение. |
InitDatasetMissingException | Исключение, указывающее, что набор данных инициализации отсутствует. |
MissingEvalDataException | Исключение, указывающее, что набор данных для оценки не был передан в сценарий. |
MissingExplainException | Исключение, указывающее, что текущее состояние является недопустимым, возможно, из-за отсутствующего вызова объяснения. |
MissingExplanationTypesException | Исключение, указывающее, что типы объяснений не были переданы. |
MissingPackageException | Исключение, связанное с отсутствующим пакетом Python, необходимым для метода. |
MissingRawTransformationsException | Исключение, указывающее, что сопоставление необработанных признаков не было передано в сценарий. |
NoExperimentNameOrIdException | Исключение, указывающее, что у эксперимента выполнения нет свойств идентификатора или имени. |
OptionalDependencyMissingException | Исключение, указывающее, что отсутствует необязательная зависимость. |
SamplesExceededException | Исключение, указывающее, что количество выборок превышает поддерживаемое максимальное значение. |
ScenarioNotSupportedException | Исключение, указывающее, что некоторый сценарий не поддерживается. |
SerializationException | Исключение, связанное с недопустимыми сериализованными данными. |
UnsupportedModelException | Исключение, указывающее, что данная модель не поддерживается. |
Обратная связь
Отправить и просмотреть отзыв по
Эта страница
Просмотреть все отзывы по странице
except и обработка разных типов исключений
Последнее обновление: 30. 01.2022
Встроенные типы исключений
В примере выше обрабатывались сразу все исключения, которые могут возникнуть в коде. Однако мы можем конкретизировать тип обрабатываемого исключения, указав его после слова except:
try: number = int(input("Введите число: ")) print("Введенное число:", number) except ValueError: print("Преобразование прошло неудачно") print("Завершение программы")
В данном случае блок execpt обрабатывает только исключения типа ValueError, которые могут возникнут при неудачном преобразовании строки в число.
В Python есть следующие базовые типы исключений:
BaseException: базовый тип для всех встроенных исключений
Exception: базовый тип, который обычно применяется для создания своих типов исключений
ArithmeticError: базовый тип для исключений, связанных с арифметическими операциями (OverflowError, ZeroDivisionError, FloatingPointError).
BufferError: тип исключения, которое возникает при невозможности выполнить операцию с буффером
LookupError: базовый тип для исключений, которое возникают при обращении в коллекциях по некорректному ключу или индексу (например, IndexError, KeyError)
От этих классов наследуются все конкретные типы исключений. В Python обладает довольно большим списком встроенных исключений. Весь этот список можно посмотреть в документации. Перечислю только некоторые наиболее часто встречающиеся:
IndexError: исключение возникает, если индекс при обращении к элементу коллекции находится вне допустимого диапазона
KeyError: возникает, если в словаре отсутствует ключ, по которому происходит обращение к элементу словаря.
OverflowError: возникает, если результат арифметической операции не может быть представлен текущим числовым типом (обычно типом float).
RecursionError: возникает, если превышена допустимая глубина рекурсии.
TypeError: возникает, если операция или функция применяется к значению недопустимого типа.
ValueError: возникает, если операция или функция получают объект корректного типа с некорректным значением.
ZeroDivisionError: возникает при делении на ноль.
NotImplementedError: тип исключения для указания, что какие-то методы класса не реализованы
ModuleNotFoundError: возникает при при невозможности найти модуль при его импорте директивой
import
OSError: тип исключений, которые генерируются при возникновении ошибок системы (например, невозможно найти файл, память диска заполнена и т.д.)
И если ситуация такова, что в программе могут быть сгенерированы различные типы исключений, то мы можем их обработать по отдельности, используя дополнительные выражения except. И при возникновении исключения Python будет искать нужный блок except, который обрабатывает данный тип исключения:
try: number1 = int(input("Введите первое число: ")) number2 = int(input("Введите второе число: ")) print("Результат деления:", number1/number2) except ValueError: print("Преобразование прошло неудачно") except ZeroDivisionError: print("Попытка деления числа на ноль") except BaseException: print("Общее исключение") print("Завершение программы")
Если возникнет исключение в результате преобразования строки в число, то оно будет обработано блоком except ValueError
.
Если же второе число будет равно нулю, то есть будет деление на ноль, тогда возникнет исключение ZeroDivisionError, и оно будет обработано блоком
except ZeroDivisionError
.
Тип BaseException представляет общее исключение, под которое попадают все исключительные ситуации. Поэтому в данном случае
любое исключение, которое не представляет тип ValueError или ZeroDivisionError, будет обработано в блоке except BaseException:
.
Однако, если в программе возникает исключение типа, для которого нет соответствующего блока except
, то программа не сможет найти соответствующий блок except и
сгенерирует исключение. Например, в следующем случае:
try: number1 = int(input("Введите первое число: ")) number2 = int(input("Введите второе число: ")) print("Результат деления:", number1/number2) except ZeroDivisionError: print("Попытка деления числа на ноль") print("Завершение программы")
Здесь предусмотрена обработка деления на ноль с помощью блока except ZeroDivisionError
. Однако если пользователь вместо числа введет некорвертиуремую в число в строку, то
возникнет исключение типа ValueError, для которого нет соответствующего блока except. И поэтому программа аварийно завершит свое выполнение.
Python позволяет в одном блоке except обрабатывать сразу несколько типов исключений. В этом случае все типы исключения передаются в скобках:
try: number1 = int(input("Введите первое число: ")) number2 = int(input("Введите второе число: ")) print("Результат деления:", number1/number2) except (ZeroDivisionError, ValueError): # обработка двух типов исключений - ZeroDivisionError и ValueError print("Попытка деления числа на ноль или некорректный ввод") print("Завершение программы")
Получение информации об исключении
С помощью оператора as мы можем передать всю информацию об исключении в переменную, которую затем можно использовать в блоке except:
try: number = int(input("Введите число: ")) print("Введенное число:", number) except ValueError as e: print("Сведения об исключении", e) print("Завершение программы")
Пример некорректного ввода:
Введите число: fdsf Сведения об исключении invalid literal for int() with base 10: 'fdsf' Завершение программы
НазадСодержаниеВперед
Exceptions Python
Введение | |
Пример с базовым Exception | |
Два исключения | |
except Error as e:: Печать текста ошибки | |
else | |
finally | |
raise | |
Пример 2 | |
Пример 3 | |
Исключения, которые не нужно обрабатывать | |
Список исключений | |
Разбор примеров: IndexError, ValueError, KeyError | |
Похожие статьи |
Введение
Если в коде есть ошибка, которую видит интерпретатор поднимается исключение, создается так называемый Exception Object, выполнение останавливается, в терминале показывается Traceback.
В английском языке используется словосочетание Raise Exception
Исключение, которое не было предусмотрено разработчиком называется необработанным (Unhandled Exception)
Такое поведение не всегда является оптимальным. Не все ошибки дожны останавливать работу кода. Возможно, где-то разработчик ожидает появление ошибок и их можно обработать по-другому.
try и except нужны прежде всего для того, чтобы код правильно реагировал на возможные ошибки и продолжал выполняться там, где появление ошибки некритично.
Исключение, которое предусмотрено в коде называется обработанным (Handled)
Блок try except имеет следующий синтаксис
try: pass except Exception: pass else: pass finally: pass
В этой статье я создал файл try_except.py куда копирую код из примеров.
Пример
Попробуем открыть несуществующий файл и воспользоваться базовым Exception
try: f = open(‘missing. txt’) except Exception: print(‘ERR: File not found’)
python try_except.py
ERR: No missing.txt file found
Ошибка поймана, видно наше сообщение а не Traceback
Проверим, что когда файл существует всё хорошо
try: f = open(‘existing.txt’) except Exception: print(‘ERR: File not found’)
python try_except.py
Пустота означает успех
Два исключения
Если ошибок больше одной нужны дополнительные исключения. Попробуем открыть существующий файл, и после этого добавить ошибку.
try: f = open(‘existing.txt’) x = bad_value except Exception: print(‘ERR: File not found’)
python try_except.py
ERR: File not found
Файл открылся, но так как в следующей строке ошибка — в терминале появилось вводящее в заблуждение сообщение. Проблема не в том, что «File not found» а в том, что bad_value нигде не определёно.
Избежать сбивающих с толку сообщений можно указав тип ожидаемой ошибки. В данном примере это FileNotFoundError
try: # expected exception f = open(‘existing.txt’) # unexpected exception should result in Traceback x = bad_value except FileNotFoundError: print(‘ERR: File not found’)
python try_except.py
Traceback (most recent call last): File «/home/andrei/python/try_except2.py», line 5, in <module> x = bad_value NameError: name ‘bad_value’ is not defined
Вторая ошибка не поймана поэтому показан Traceback
Поймать обе ошибки можно добавив второй Exception
try: # expected exception should be caught by FileNotFoundError f = open(‘missing.txt’) # unexpected exception should be caught by Exception x = bad_value except FileNotFoundError: print(‘ERR: File not found’) except Exception: print(‘ERR: Something unexpected went wrong’)
python try_except. py
ERR: File not found
ERR: Something unexpected went wrong
Печать текста ошибки
Вместо своего текста можно выводить текст ошибки. Попробуем с существующим файлом — должна быть одна пойманная ошибка.
try: # expected exception should be caught by FileNotFoundError f = open(‘existing.txt’) # unexpected exception should be caught by Exception x = bad_value except FileNotFoundError as e: print(e) except Exception as e: print(e)
python try_except.py
name ‘bad_value’ is not defined
Теперь попытаемся открыть несуществующий файл — должно быть две пойманные ошибки.
try: # expected exception should be caught by FileNotFoundError f = open(‘missing.txt’) # unexpected exception should be caught by Exception x = bad_value except FileNotFoundError as e: print(e) except Exception as e: print(e)
python try_except. py
name ‘bad_value’ is not defined
[Errno 2] No such file or directory: ‘missing.txt’
else
Блок else будет выполнен если исключений не будет поймано.
Попробуем открыть существующий файл existing.txt в котором есть строка www.heihei.ru
try: f = open(‘existing.txt’) except FileNotFoundError as e: print(e) except Exception as e: print(e) else: print(f.read()) f.close()
python try_except.py
www.heihei.ru
Если попробовать открыть несуществующий файл missing.txt то исключение обрабатывается, а код из блока else не выполняется.
[Errno 2] No such file or directory: ‘missing.txt’
finally
Блок finally будет выполнен независимо от того, поймано исключение или нет
try: f = open(‘existing. txt’) except FileNotFoundError as e: print(e) except Exception as e: print(e) else: print(f.read()) f.close() finally: print(«Finally!»)
www.heihei.ru Finally!
А если попытаться открыть несуществующий missing.txt
[Errno 2] No such file or directory: ‘missing.txt’ Finally!
Когда нужно применять finally:
Рассмотрим скрипт, который вносит какие-то изменения в систему. Затем он пытается что-то сделать. В конце возвращает систему в исходное состояние.
Если ошибка случится в середине скрипта — он уже не сможет вернуть систему в исходное состояние.
Но если вынести возврат к исходному состоянию в блок finally он сработает даже при ошибке в предыдущем блоке.
import os def make_at(path, dir_name): original_path = os.getcwd() os.chdir(path) os.mkdir(dir_name) os.chdir(original_path)
Этот скрипт не вернётся в исходную директорию при ошибке в os. mkdir(dir_name)
А у скрипта ниже такой проблемы нет
def make_at(path, dir_name): original_path = os.getcwd() os.chdir(path) try: os.mkdir(dir_name) finally: os.chdir(original_path)
Не лишнима будет добавить обработку и вывод исключения
import os import sys def make_at(path, dir_name): original_path = os.getcwd() os.chdir(path) try: os.mkdir(dir_name) except OSError as e: print(e, file=sys.stderr) raise finally: os.chdir(original_path)
По умолчанию print() выводит в sys.stdout, но в случае ислючений логичнее выводить в sys.stderr
raise
Можно вызывать исключения вручную в любом месте кода с помощью raise.
try: f = open(‘outdated.txt’) if f.name == ‘outdated.txt’: raise Exception except FileNotFoundError as e: print(e) except Exception as e: print(‘File is outdated!’) else: print(f. read()) f.close() finally: print(«Finally!»)
python try_except.py
File is outdated! Finally!
raise можно использовать для перевызова исключения, например, чтобы уйти от использования кодов ошибок.
Для этого достаточно вызвать raise без аргументов — поднимется текущее исключение.
Пример 2
Рассмотрим функцию, которая принимает числа прописью и возвращает цифрами
DIGIT_MAP = { ‘zero’: ‘0’, ‘one’: ‘1’, ‘two’: ‘2’, ‘three’: ‘3’, ‘four’: ‘4’, ‘five’: ‘5’, ‘six’: ‘6’, ‘seven’: ‘7’, ‘eight’: ‘8’, ‘nine’: ‘9’, } def convert(s): number = » for token in s: number += DIGIT_MAP[token] x = int(number) return x
python
>>> from exc1 import convert >>> convert(«one three three seven».split()) 1337
Теперь передадим аргумент, который не предусмотрен в словаре
>>> convert(«something unseen». split()) Traceback (most recent call last): File «<stdin>», line 1, in <module> File «/home/andrei/python/exc1.py», line 17, in convert number &plu= DIGIT_MAP[token] KeyError: ‘something’
KeyError — это тип Exception объекта. Полный список можно изучить в конце статьи.
Исключение прошло следующий путь:
REPL → convert() → DIGIT_MAP(«something») → KeyError
Обработать это исключение можно внеся изменения в функцию convert
convert(s): try: number = » for token in s: number += DIGIT_MAP[token] x = int(number) print(«Conversion succeeded! x = «, x) except KeyError: print(«Conversion failed!») x = -1 return x
>>> from exc1 import convert >>> convert(«one nine six one».split()) Conversion succeeded! x = 1961 1961 >>> convert(«something unseen».split()) Conversion failed! -1
Эта обработка не спасает если передать int вместо итерируемого объекта
>>> convert(2022) Traceback (most recent call last): File «<stdin>», line 1, in <module> File «/home/andrei/python/exc1. py», line 17, in convert for token in s: TypeError: ‘int’ object is not iterable
Нужно добавить обработку TypeError
… except KeyError: print(«Conversion failed!») x = -1 except TypeError: print(«Conversion failed!») x = -1 return x
>>> from exc1 import convert >>> convert(«2022».split()) Conversion failed! -1
Избавимся от повторов, удалив принты, объединив два исключения в кортеж и вынесем присваивание значения x из try блока.
Также добавим докстринг с описанием функции.
def convert(s): «»»Convert a string to an integer.»»» x = -1 try: number = » for token in s: number += DIGIT_MAP[token] x = int(number) except (KeyError, TypeError): pass return x
>>> from exc4 import convert >>> convert(«one nine six one».split()) 1961 >>> convert(«bad nine six one». split()) -1 >>> convert(2022) -1
Ошибки обрабатываются, но без принтов, процесс не очень информативен.
Грамотно показать текст сообщений об ошибках можно импортировав sys и изменив функцию
import sys DIGIT_MAP = { ‘zero’: ‘0’, ‘one’: ‘1’, ‘two’: ‘2’, ‘three’: ‘3’, ‘four’: ‘4’, ‘five’: ‘5’, ‘six’: ‘6’, ‘seven’: ‘7’, ‘eight’: ‘8’, ‘nine’: ‘9’, } def convert(s): «»»Convert a string to an integer.»»» try: number = » for token in s: number += DIGIT_MAP[token] return(int(number)) except (KeyError, TypeError) as e: print(f»Conversion error: {e!r}», file=sys.stderr) return -1
>>> from exc1 import convert >>> convert(2022) Conversion error: TypeError(«‘int’ object is not iterable») -1 >>> convert(«one nine six one».split()) 1961 >>> convert(«bad nine six one».split()) Conversion error: KeyError(‘bad’)
Ошибки обрабатываются и их текст виден в терминале.
С помощью !r выводится repr() ошибки
raise вместо кода ошибки
В предыдущем примере мы полагались на возвращение числа -1 в качестве кода ошибки.
Добавим к коду примера функцию string_log() и поработаем с ней
def string_log(s): v = convert(s) return log(v)
>>> from exc1 import string_log >>> string_log(«one two eight».split()) 4.852030263919617 >>> string_log(«bad one two».split()) Conversion error: KeyError(‘bad’) Traceback (most recent call last): File «<stdin>», line 1, in <module> File «/home/andrei/exc1.py», line 32, in string_log return log(v) ValueError: math domain error
convert() вернул -1 а string_log попробовал его обработать и не смог.
Можно заменить return -1 на raise. Это считается более правильным подходом в Python
def convert(s): «»»Convert a string to an integer. «»» try: number = » for token in s: number += DIGIT_MAP[token] return(int(number)) except (KeyError, TypeError) as e: print(f»Conversion error: {e!r}», file=sys.stderr) raise
>>> from exc7 import string_log >>> string_log(«one zero».split()) 2.302585092994046 >>> string_log(«bad one two».split()) Conversion error: KeyError(‘bad’) Traceback (most recent call last): File «<stdin>», line 1, in <module> File «/home/andrei/exc7.py», line 31, in string_log v = convert(s) File «/home/andrei/exc7.py», line 23, in convert number += DIGIT_MAP[token] KeyError: ‘bad’
Пример 3
Рассмотрим алгоритм по поиску квадратного корня
def sqrt(x): «»»Compute square roots using the method of Heron of Alexandria. Args: x: The number for which the square root is to be computed. Returns: The square root of x. «»» guess = x i = 0 while guess * guess != x and i < 20: guess = (guess + x / guess) / 2.0 i += 1 return guess def main(): print(sqrt(9)) print(sqrt(2)) if __name__ == ‘__main__’: main()
python sqrt_ex.py
3.0 1.414213562373095
При попытке вычислить корень от -1 получим ошибку
def main(): print(sqrt(9)) print(sqrt(2)) print(sqrt(-1))
python sqrt_ex.py
3.0 1.414213562373095 Traceback (most recent call last): File «/home/andrei/sqrt_ex.py», line 26, in <module> main() File «/home/andrei/sqrt_ex.py», line 23, in main print(sqrt(-1)) File «/home/andrei/sqrt_ex.py», line 16, in sqrt guess = (guess + x / guess) / 2.0 ZeroDivisionError: float division by zero
В строке
guess = (guess + x / guess) / 2.0
Происходит деление на ноль
Обработать можно следующим образом:
def main(): try: print(sqrt(9)) print(sqrt(2)) print(sqrt(-1)) except ZeroDivisionError: print(«Cannot compute square root » «of a negative number. «) print(«Program execution continues » «normally here.»)
Обратите внимание на то, что в try помещены все вызовы функции
python sqrt_ex.py
3.0 1.414213562373095 Cannot compute square root of a negative number. Program execution continues normally here.
Если пытаться делить на ноль несколько раз — поднимется одно исключение и всё что находится в блоке try после выполняться не будет
def main(): try: print(sqrt(9)) print(sqrt(-1)) print(sqrt(2)) print(sqrt(-1))
python sqrt_ex.py
3.0 Cannot compute square root of a negative number. Program execution continues normally here.
Каждую попытку вычислить корень из -1 придётся обрабатывать отдельно. Это кажется неудобным, но в этом и заключается смысл — каждое место где вы ждёте ислючение нужно помещать в свой try except блок.
Можно обработать исключение так:
try: while guess * guess != x and i < 20: guess = (guess + x / guess) / 2. 0 i += 1 except ZeroDivisionError: raise ValueError() return guess def main(): print(sqrt(9)) print(sqrt(-1))
python sqrt_ex.py
3.0 Traceback (most recent call last): File «/home/andrei/sqrt_ex3.py», line 17, in sqrt guess = (guess + x / guess) / 2.0 ZeroDivisionError: float division by zero During handling of the above exception, another exception occurred: Traceback (most recent call last): File «/home/andrei/sqrt_ex3.py», line 30, in <module> main() File «/home/andrei/sqrt_ex3.py», line 25, in main print(sqrt(-1)) File «/home/andrei/sqrt_ex3.py», line 20, in sqrt raise ValueError() ValueError
Гораздо логичнее поднимать исключение сразу при получении аргумента
def sqrt(x): «»»Compute square roots using the method of Heron of Alexandria. Args: x: The number for which the square root is to be computed. Returns: The square root of x. Raises: ValueError: If x is negative «»» if x < 0: raise ValueError( «Cannot compute square root of » f»negative number {x}») guess = x i = 0 while guess * guess != x and i < 20: guess = (guess + x / guess) / 2.0 i += 1 return guess def main(): print(sqrt(9)) print(sqrt(-1)) print(sqrt(2)) print(sqrt(-1)) if __name__ == ‘__main__’: main()
python sqrt_ex.py
3.0 Traceback (most recent call last): File «/home/avorotyn/python/lessons/pluralsight/core_python_getting_started/chapter8/sqrt_ex4.py», line 35, in <module> main() File «/home/avorotyn/python/lessons/pluralsight/core_python_getting_started/chapter8/sqrt_ex4.py», line 30, in main print(sqrt(-1)) File «/home/avorotyn/python/lessons/pluralsight/core_python_getting_started/chapter8/sqrt_ex4.py», line 17, in sqrt raise ValueError( ValueError: Cannot compute square root of negative number -1
Пока получилось не очень — виден Traceback
Убрать Traceback можно добавив обработку ValueError в вызов функций
import sys def sqrt(x): «»»Compute square roots using the method of Heron of Alexandria. Args: x: The number for which the square root is to be computed. Returns: The square root of x. Raises: ValueError: If x is negative «»» if x < 0: raise ValueError( «Cannot compute square root of » f»negative number {x}») guess = x i = 0 while guess * guess != x and i < 20: guess = (guess + x / guess) / 2.0 i += 1 return guess def main(): try: print(sqrt(9)) print(sqrt(2)) print(sqrt(-1)) print(«This is never printed») except ValueError as e: print(e, file=sys.stderr) print(«Program execution continues normally here.») if __name__ == ‘__main__’: main()
python sqrt_ex.py
3.0 1.414213562373095 Cannot compute square root of negative number -1 Program execution continues normally here.
Исключения, которые не нужно обрабатывать
IndentationError, SyntaxError, NameError нужно исправлять в коде а не пытаться обработать.
Важно помнить, что использовать обработку исключений для замалчивания ошибок программиста недопустимо.
Список исключений
Список встроенных в Python исключений
Существуют следующие типы объектов Exception
BaseException +— SystemExit +— KeyboardInterrupt +— GeneratorExit +— Exception +— StopIteration +— StopAsyncIteration +— ArithmeticError | +— FloatingPointError | +— OverflowError | +— ZeroDivisionError +— AssertionError +— AttributeError +— BufferError +— EOFError +— ImportError | +— ModuleNotFoundError +— LookupError | +— IndexError | +— KeyError +— MemoryError +— NameError | +— UnboundLocalError +— OSError | +— BlockingIOError | +— ChildProcessError | +— ConnectionError | | +— BrokenPipeError | | +— ConnectionAbortedError | | +— ConnectionRefusedError | | +— ConnectionResetError | +— FileExistsError | +— FileNotFoundError | +— InterruptedError | +— IsADirectoryError | +— NotADirectoryError | +— PermissionError | +— ProcessLookupError | +— TimeoutError +— ReferenceError +— RuntimeError | +— NotImplementedError | +— RecursionError +— SyntaxError | +— IndentationError | +— TabError +— SystemError +— TypeError +— ValueError | +— UnicodeError | +— UnicodeDecodeError | +— UnicodeEncodeError | +— UnicodeTranslateError +— Warning +— DeprecationWarning +— PendingDeprecationWarning +— RuntimeWarning +— SyntaxWarning +— UserWarning +— FutureWarning +— ImportWarning +— UnicodeWarning +— BytesWarning +— EncodingWarning +— ResourceWarning
IndexError
Объекты, которые поддерживают протокол Sequence должны поднимать исключение IndexError при использовании несуществующего индекса.
IndexError как и KeyError относится к ошибкам поиска LookupError
Пример
>>> a = [0, 1, 2] >>> a[3]
Traceback (most recent call last): File «<stdin>», line 1, in <module> IndexError: list index out of range
ValueError
ValueError поднимается когда объект правильного типа, но содержит неправильное значение
>>> int(«text»)
Traceback (most recent call last): File «<stdin>», line 1, in <module> ValueError: invalid literal for int() with base 10: ‘text’
KeyError
KeyError поднимается когда поиск по ключам не даёт результата
>>> sites = dict(urn=1, heihei=2, eth2=3) >>> sites[«topbicycle»]
Traceback (most recent call last): File «<stdin>», line 1, in <module> KeyError: ‘topbicycle’
Python | |
Интерактивный режим | |
str: строки | |
\: перенос строки | |
Списки [] | |
if, elif, else | |
Циклы | |
Функции | |
Пакеты | |
*args **kwargs | |
ООП | |
enum | |
Опеределить тип переменной Python | |
Тестирование с помощью Python | |
Работа с REST API на Python | |
Файлы: записать, прочитать, дописать, контекстный менеджер… | |
Скачать файл по сети | |
SQLite3: работа с БД | |
datetime: Дата и время в Python | |
json. dumps | |
Selenium + Python | |
Сложности при работе с Python | |
DJANGO | |
Flask | |
Скрипт для ZPL принтера | |
socket :Python Sockets | |
Виртуальное окружение | |
subprocess: выполнение bash команд из Python | |
multiprocessing: несколько процессов одновременно | |
psutil: cистемные ресурсы | |
sys.argv: аргументы командной строки | |
PyCharm: IDE | |
pydantic: валидация данных | |
paramiko: SSH из Python | |
enumerate | |
logging: запись в лог | |
Обучение программированию на Python |
Применение exception при накате Python-скрипта на Huawei / Хабр
Обычно мы можем встретить три проблемы при попытке запустить Python-скрипт на сети Huawei (впрочем, и на любой другой): это отсутствие L3 связности с устройством, это неверные имя пользователя или пароль, и это SSH-неполадки. Можно заметить, что любая из этих проблем остановит накат скрипта и сгенерирует один и тот же лог, большая часть из которого сложна для восприятия. В этой статье я постарался рассказать о небольшом улучшении предыдущего кода, которое сообщит о конкретной ошибке на устройстве, и продолжит накат скрипта дальше.
Запуск кода можно посмотреть на видео демонстрации.
Вывод лога ошибки без применения конструкции try — except — continueЯ буду использовать Python конструкцию try — except — continue. try позволяет протестировать блок кода на ошибки. except (exception или исключения) — это тип данных Python, который позволяет сообщить об ошибке. Большинство исключений уже описаны и встроены в Python, нужно лишь найти подходящий.
Я также буду использовать оператор continue, чтобы накат скрипта продолжился несмотря на возникновение ошибки. А функция print() выведет заданное сообщение, если сработает то или иное исключение (except). Иными словами, если не удастся подключиться к устройству из списка устройств, то скрипт выведет короткое сообщение почему именно не удалось подключиться, и попытается подключиться к следующему устройству и так далее. Если ошибки не возникает, то код except пропускается. Еще раз подчеркну, что возникновение ошибки без конструкции try — except — continue, во-первых, сразу останавливает накат скрипта, то есть попытки подключения к другим устройствам из списка не происходит, а во-вторых, сгенерированный лог сообщения является длинным и беcсодержательным.
Итак, Python имеет встроенные исключения (except), которые описывают конкретные ошибки. Например:
Ошибка аутентификации — AuthenticationException
Ошибка недоступности — NetMikoTimeoutException
Ошибка SSH — SSHException
Блок кода except срабатывает только, если происходит ошибка. В этот блок входит функция print() и оператор continue. Например, если указать неверный пароль, то на экран будет выведено сообщение “Неверные данные аутентификации: ip-адрес устройства”. Если ни одна из ошибок не случится, то все три блока кода except будут пропущены, и отработает только главное задание скрипта — send_config_set (последняя строчка кода на примере выше).
Все указанные исключения нужно импортировать через соответствующие модули:
from netmiko.ssh_exception import NetMikoTimeoutException from paramiko.ssh_exception import SSHException from netmiko.ssh_exception import AuthenticationException
Весь код приведу в конце статьи.
Теперь тест в eNSP. В топологии восемь CloudEngine Huawei коммутатор. Из них я включу только три, остальные пять останутся недоступными (при попытке подключиться к ним скрипт должен вывести сообщение “Нет ответа от устройства: ip-адрес”). Первый коммутатор оставлю без ошибок, то есть на нем должно отработать задание автоматизации (накат конфигурации), на втором изменю пароль, а на третьем отключу SSH.
Топология eNSP для тестирования отработки ошибокИзменяю пароль на CE2:
<CE_2>sys
Enter system view, return user view with return command.
[~CE_2]aaa
[~CE_2-aaa]local-user vasyo1 password irreversible-cipher @ghjcnjnF3589866
[*CE_2-aaa]commit
Отключаю SSH на VTY линиях на CE_3:
<CE_3>sys
Enter system view, return user view with return command.
[~CE_3]user-interface vty 0 4
[~CE_3-ui-vty0-4]protocol inbound telnet
[*CE_3-ui-vty0-4]commit
Теперь запущу скрипт:
Применение exception при накате Python-скрипта на HuaweiПервые строчки после Password — это содержание файлов в формате JSON, а именно файла, содержащего команды конфигурации, и файла, содержащего список IP-адресов устройств. Далее в первом красном прямоугольнике успешный накат конфигурации, во втором красном прямоугольнике сообщение о неверно введеных данных аутентификации (где я поменял пароль), и третий прямоугольник сообщает о недоступности SSH (где я разрешил использовать только telnet). Остальные пять коммутаторов: нет ответа от устройства и их IP-адреса (которые я и не включал).
Можно говорить об успешном применении конструкции try — except — continue.
Может посмотреть видео демонстарию наката, исходный код и его описание в статье: Мой друг Netmiko. Часть 2: Три улучшения Python-скрипта.
Полный код:
from getpass import getpass from netmiko import ConnectHandler from netmiko.ssh_exception import NetMikoTimeoutException from paramiko.ssh_exception import SSHException from netmiko.ssh_exception import AuthenticationException username = input('Введите имя пользователя SSH: ') password = getpass() with open('switch_file_config') as f: config_lines = f.read().splitlines() print (config_lines) with open('myswitches') as f: ip_lines = f.read().splitlines() print (ip_lines) for device in ip_lines: ip_address_of_device = device CE = { 'device_type': 'huawei', 'ip': ip_address_of_device, 'username': username, 'password': password } try: ssh_connect = ConnectHandler(**CE) except (AuthenticationException): print ('Неверные данные аутентификации: ' + ip_address_of_device) continue except (NetMikoTimeoutException): print ('Нет ответа от устройства: ' + ip_address_of_device) continue except (SSHException): print ('SSH недоступен. Проверьте включен ли SSH? ' + ip_address_of_device) continue output = ssh_connect.send_config_set(config_lines) print(f"\n\n-------------- CE_{CE['ip']} --------------") print(output) print("-------------------- End -------------------")
Литература:
https://stackoverflow.com/questions/5563089/raw-input-function-in-python
https://pynet.twb-tech.com/blog/automation/netmiko.html
https://pyneng.readthedocs.io/en/latest/book/18_ssh_telnet/netmiko.html
https://github.com/ktbyers/netmiko
https://github.com/ktbyers/netmiko/blob/master/netmiko/ssh_dispatcher.py
Udemy.com — Python Network Programming for Network Engineers (Python 3) (David Bombal)
python exceptions — Конспекты (2022.09)
raise RuntimeError(u'Ошибка какая то')
class MyException(Exception): pass
assert False, u'Данная строка возбудит исключение AssertionError'
AttributeError()
- class
AttributeError
Возбуждается при обращении к несуществующему атрибуту
Наследник
StandardError
ArithmeticError()
- class
ArithmeticError
Базовый класс исключений, возбуждаемых арифметическими операциями
Наследник
StandardError
AssertionError()
- class
AssertionError
Возбуждается инструкциями assert
Наследник
StandardError
BaseException()
- class
BaseException
Базовый класс всех исключений
EnvironmentError()
- class
EnvironmentError
Ошибка, обусловленная внешними причинами
Наследник
StandardError
EOFError()
- class
EOFError
Возбуждается по достижении конца файла
Наследник
StandardError
Exception()
- class
Exception
Базовый класс для всех исключений, не связанных с завершением программы
Наследник
BaseException
FloatingPointError()
- class
FloatingPointError
Ошибка в инструкции import
Наследник
ArithmeticError
GeneratorExit()
- class
GeneratorExit
Возбуждается методом . close() генераторов
Наследник
BaseException
ImportError()
- class
ImportError
Ошибка в инструкции import
Наследник
SyntaxError
IndentationError()
- class
IndentationError
Ошибка оформления отступов
Наследник
SyntaxError
IndexError()
- class
IndexError
Ошибка обращения по индексу за пределами последовательности.
Наследник
LookupError
IOError()
- class
IOError
Ошибка ввода-вывода при работе с файлами
Наследник
EnvironmentError
KeyError()
- class
KeyError
Ошибка обращения к несуществующему ключу словаря
Наследник
LookupError
KeyboardInterrupt()
- class
KeyboardInterrupt
Возбуждается нажатием клавишей прерывания (обычно Ctrl-C)
Наследник
BaseException
LookupError()
- class
LookupError
Ошибка обращения по индексу или ключу
Наследник
Exception
MemoryError()
- class
MemoryError
Нехватка памяти
Наследник
Exception
NameError()
- class
NameError
Не удалось отыскать локальное или глобальное имя
Наследник
Exception
NotImplementedError()
- class
NotImplementedError
Обращение к нереализованному методу или функции
Наследник
Exception
OSError()
- class
OSError
Ошибка операционной системы
Наследник
EnvironmentError
ReferenceError()
- class
ReferenceError
Ошибка обращения к объекту, который уже был уничтожен
Наследник
Exception
RuntimeError()
- class
RuntimeError
Универсальное исключение
Наследник
Exception
StandardError()
- class
StandardError
Базовый класс для всех встроенных исключений (только в Python 2).
В Python 3 – базовый класс всех исключений, наследующих класс Exception
Наследник
Exception
StopIteration()
- class
StopIteration
Возбуждается для прекращения итераций
Наследник
Exception
SyntaxError()
- class
SyntaxError
Синтаксическая ошибка
Наследник
Exception
SystemError()
- class
SystemError
Нефатальная системная ошибка в интерпретаторе
Наследник
Exception
SystemExit()
- class
SystemExit
Завершение программы
Наследник
BaseException
TabError()
- class
TabError
Непоследовательное использование символа табуляции (генерируется при запуске интерпретатора с ключом –tt)
Наследник
IndentationError
TypeError()
- class
TypeError
Попытка выполнить операцию над аргументом недопустимого типа
Наследник
Exception
UnboundLocalError()
- class
UnboundLocalError
Ошибка обращения к локальной переменной, которой еще не было присвоено значение
Наследник
Exception
UnicodeError()
- class
UnicodeError
Ошибка при работе с символами Юникода
Наследник
ValueError
UnicodeDecodeError()
- class
UnicodeDecodeError
Ошибка декодирования символов Юникода
Наследник
ValueError
UnicodeEncodeError()
- class
UnicodeEncodeError
Ошибка кодирования символов Юникода
Наследник
ValueError
UnicodeTranslateError()
- class
UnicodeTranslateError
Ошибка трансляции символов Юникода
Наследник
ValueError
ValueError()
- class
ValueError
Недопустимый тип
Наследник
Exception
ZeroDivisionError()
- class
ZeroDivisionError
Деление или деления по модулю на ноль
Наследник
ArithmeticError
Введение — Real Python
Смотреть сейчас Это руководство содержит соответствующий видеокурс, созданный командой Real Python. Посмотрите его вместе с письменным учебным пособием, чтобы углубить свое понимание: Создание и обработка исключений Python
Программа Python завершает работу, как только обнаруживает ошибку. В Python ошибка может быть синтаксической ошибкой или исключением. В этой статье вы увидите, что такое исключение и чем оно отличается от синтаксической ошибки. После этого вы узнаете о возбуждении исключений и создании утверждений. Затем вы закончите демонстрацией блока try и exclude. 9SyntaxError: неверный синтаксис
Стрелка указывает, где синтаксический анализатор столкнулся с синтаксической ошибкой . В этом примере было на одну скобку слишком много. Удалите его и снова запустите свой код:
.>>> печать (0 / 0) Traceback (последний последний вызов): Файл "", строка 1, в ZeroDivisionError: целочисленное деление или по модулю на ноль
На этот раз вы столкнулись с ошибкой исключения . Этот тип ошибки возникает всякий раз, когда синтаксически правильный код Python приводит к ошибке. В последней строке сообщения указано, с каким типом ошибки исключения вы столкнулись.
Вместо того, чтобы показывать сообщение ошибка исключения
, Python детализирует тип обнаруженной ошибки исключения. В данном случае это был ZeroDivisionError
. Python поставляется с различными встроенными исключениями, а также с возможностью создавать собственные исключения.
Удалить рекламу
Вызов исключения
Мы можем использовать , поднять
, чтобы вызвать исключение, если возникнет условие. Оператор может быть дополнен пользовательским исключением.
Если вы хотите выдать ошибку при возникновении определенного условия, используя поднять
, вы можете сделать это следующим образом:
х = 10 если х > 5: поднять Exception('x не должен превышать 5. Значение x было: {}'.format(x))
Когда вы запустите этот код, вывод будет следующим:
Трассировка (последний последний вызов): Файл "", строка 4, вИсключение: x не должен превышать 5. Значение x было: 10
Программа останавливается и отображает наше исключение на экране, предлагая подсказки о том, что пошло не так.
AssertionError
Исключение Вместо того, чтобы ждать сбоя программы на полпути, вы также можете начать с утверждения в Python. Мы утверждаем
, что определенное условие выполнено. Если это условие окажется True
, то это отлично! Программа может продолжаться. Если условие оказывается False
, вы можете заставить программу выдать исключение AssertionError
.
Взгляните на следующий пример, где утверждается, что код будет выполняться в системе Linux:
система импорта assert («linux» в sys.platform), «Этот код работает только в Linux».
Если вы запустите этот код на компьютере с Linux, утверждение пройдет успешно. Если бы вы запустили этот код на компьютере с Windows, результат утверждения был бы False
, а результат был бы следующим:
Трассировка (последний последний вызов): Файл "", строка 2, вAssertionError: этот код работает только в Linux.
В этом примере выпадение 9Исключение 0026 AssertionError — это последнее, что сделает программа. Программа остановится и не будет продолжаться. Что, если это не то, чего вы хотите?
попробовать
и кроме
Блок: Обработка исключений Блоки try
и exclude
в Python используются для перехвата и обработки исключений. Python выполняет код, следующий за оператором try
, как «нормальную» часть программы. Код, который следует за , кроме 9Оператор 0027 — это ответ программы на любые исключения в предыдущем предложении
try
.
Как вы видели ранее, когда синтаксически правильный код сталкивается с ошибкой, Python выдает ошибку исключения. Эта ошибка исключения приведет к сбою программы, если она не обработана. Предложение , кроме
, определяет, как ваша программа реагирует на исключения.
Следующая функция может помочь вам понять , попробуйте
и , кроме блока
:
по умолчанию linux_interaction(): assert («linux» в sys.platform), «Функция может работать только в системах Linux». print('Что-то делаю.')
linux_interaction()
может работать только в системе Linux. assert
в этой функции вызовет исключение AssertionError
, если вы вызовете его в операционной системе, отличной от Linux.
Вы можете дать функции попробовать
, используя следующий код:
попробуйте: linux_interaction() кроме: проходить
Здесь вы обработали ошибку, выдав пропуск
. Если бы вы запустили этот код на компьютере с Windows, вы бы получили следующий вывод:
У тебя ничего нет. Хорошо, что программа не дала сбой. Но было бы неплохо увидеть, возникало ли какое-либо исключение всякий раз, когда вы запускали свой код. С этой целью вы можете изменить pass
на что-то, что будет генерировать информативное сообщение, например:
попробуйте: linux_interaction() кроме: print('Функция Linux не была выполнена')
Выполните этот код на компьютере с Windows:
Функция Linux не была выполнена
При возникновении исключения в программе, выполняющей эту функцию, программа продолжит работу, а также сообщит вам о том, что вызов функции не увенчался успехом.
Чего вы не увидели, так это типа ошибки, возникшей в результате вызова функции. Чтобы точно увидеть, что пошло не так, вам нужно поймать ошибку, которую выдала функция.
Следующий код является примером захвата AssertionError
и вывода этого сообщения на экран:
попробуйте: linux_interaction() кроме AssertionError как ошибки: распечатать (ошибка) print('Функция linux_interaction() не была выполнена')
Запуск этой функции на компьютере с Windows выводит следующее:
Функция может работать только в системах Linux. Функция linux_interaction() не была выполнена
Первое сообщение — AssertionError
, информирующее вас о том, что функция может выполняться только на компьютере с Linux. Второе сообщение сообщает вам, какая функция не была выполнена.
В предыдущем примере вы вызвали функцию, которую написали сами. Когда вы выполнили функцию, вы перехватили исключение AssertionError
и вывели его на экран.
Вот еще один пример, когда вы открываете файл и используете встроенное исключение:
попробуйте: с open('file.log') в качестве файла: read_data = файл.read() кроме: print('Не удалось открыть файл.log')
Если file.log не существует, этот блок кода выведет следующее:
Не удалось открыть файл.log
Это информационное сообщение, и наша программа продолжит работу. В документации по Python вы можете увидеть множество встроенных исключений, которые вы можете здесь использовать. На этой странице описано одно исключение:
.Исключение
FileNotFoundError
Возникает, когда запрошен файл или каталог, но он не существует. Соответствует errno ENOENT.
Чтобы перехватить этот тип исключения и вывести его на экран, вы можете использовать следующий код:
попробуйте: с open('file.log') в качестве файла: read_data = файл.read() кроме FileNotFoundError как fnf_error: печать (fnf_error)
В этом случае, если file.log не существует, вывод будет следующим:
[Errno 2] Нет такого файла или каталога: 'file.log'
Вы можете иметь более одного вызова функции в предложении try
и ожидать перехвата различных исключений. Здесь следует отметить, что код в try 9Предложение 0027 остановится, как только возникнет исключение.
Предупреждение: Перехват Исключение
скрывает все ошибки... даже совершенно неожиданные. Вот почему вам следует избегать голых предложений , кроме
, в ваших программах на Python. Вместо этого вам нужно обратиться к конкретным классам исключений, которые вы хотите поймать и обработать. Вы можете узнать больше о том, почему это хорошая идея, в этом уроке.
Посмотрите на следующий код. Здесь вы сначала звоните linux_interaction()
, а затем попытайтесь открыть файл:
попробуйте: linux_interaction() с open('file.log') в качестве файла: read_data = файл.read() кроме FileNotFoundError как fnf_error: печать (fnf_error) кроме AssertionError как ошибки: распечатать (ошибка) print('Функция Linux linux_interaction() не была выполнена')
Если файл не существует, запуск этого кода на компьютере с Windows выведет следующее:
Функция может работать только в системах Linux. Функция Linux linux_interaction() не была выполнена
Внутри предложения try
вы сразу столкнулись с исключением и не дошли до той части, где вы пытаетесь открыть file.log . Теперь посмотрите, что происходит, когда вы запускаете код на машине с Linux:
[Errno 2] Нет такого файла или каталога: 'file.log'
Вот основные выводы:
- Предложение
try
выполняется до тех пор, пока не встретится первое исключение. - В предложении
, кроме
, или в обработчике исключений вы определяете, как программа реагирует на исключение. 902:30 - Вы можете предвидеть несколько исключений и различать, как программа должна реагировать на них.
- Избегайте использования голых предложений
, кроме
.
Удалить рекламу
Остальное
Пункт В Python с помощью оператора else
вы можете указать программе выполнять определенный блок кода только при отсутствии исключений.
Посмотрите на следующий пример:
попробуйте: linux_interaction() кроме AssertionError как ошибки: распечатать (ошибка) еще: print('Выполнение условия else.')
Если бы вы запустили этот код в системе Linux, вывод был бы следующим:
Что-то делать. Выполнение предложения else.
Поскольку программа не столкнулась с какими-либо исключениями, было выполнено предложение else
.
Вы также можете попробовать
запустить код внутри предложения else
и перехватить там возможные исключения:
попробуйте: linux_interaction() кроме AssertionError как ошибки: распечатать (ошибка) еще: пытаться: с open('file.log') в качестве файла: read_data = файл.read() кроме FileNotFoundError как fnf_error: печать (fnf_error)
Если бы вы выполнили этот код на компьютере с Linux, вы бы получили следующий результат:
Что-то делать. [Errno 2] Нет такого файла или каталога: 'file.log'
Из вывода видно, что функция linux_interaction()
запущена. Поскольку никаких исключений обнаружено не было, была предпринята попытка открыть файл file.log . Этот файл не существовал, и вместо того, чтобы открыть файл, вы поймали исключение FileNotFoundError
.
Уборка после использования
наконец
Представьте, что вам всегда приходилось выполнять какое-то действие для очистки после выполнения вашего кода. Python позволяет вам сделать это с помощью предложения finally
.
Взгляните на следующий пример:
попробуйте: linux_interaction() кроме AssertionError как ошибки: распечатать (ошибка) еще: пытаться: с open('file.log') в качестве файла: read_data = файл.read() кроме FileNotFoundError как fnf_error: печать (fnf_error) в конце концов: print('Очистка вне зависимости от каких-либо исключений.')
В предыдущем коде все в предложении finally
будет выполнено. Неважно, встретите ли вы исключение где-нибудь в предложениях try
или else
. Выполнение предыдущего кода на компьютере с Windows приведет к следующему результату:
Функция может работать только в системах Linux. Уборка вне зависимости от каких-либо исключений.
Удалить рекламу
Подведение итогов
Увидев разницу между синтаксическими ошибками и исключениями, вы узнали о различных способах создания, перехвата и обработки исключений в Python. В этой статье вы увидели следующие варианты:
-
поднять
позволяет вам создать исключение в любое время. -
assert
позволяет вам проверить, выполняется ли определенное условие, и выдать исключение, если это не так. - В предложении
try
все операторы выполняются до тех пор, пока не встретится исключение. -
, кроме
, используется для перехвата и обработки исключений, встречающихся в предложении try. -
else
позволяет вам кодировать разделы, которые должны запускаться только тогда, когда в предложении try не встречаются исключения. 902:30 -
наконец
позволяет выполнять разделы кода, которые должны выполняться всегда, с какими-либо ранее встречавшимися исключениями или без них.
Надеюсь, эта статья помогла вам понять основные инструменты, которые Python может предложить при работе с исключениями.
Смотреть сейчас Это руководство содержит связанный с ним видеокурс, созданный командой Real Python. Посмотрите его вместе с письменным учебным пособием, чтобы углубить свое понимание: Raising and Handling Python Exceptions
Ошибки Python и встроенные исключения
В этом руководстве вы узнаете о различных типах ошибок и исключений, встроенных в Python. Они возникают всякий раз, когда интерпретатор Python обнаруживает ошибки.
Видео: обработка исключений Python
При написании программы мы можем допустить определенные ошибки, которые приведут к ошибкам при попытке ее запуска. Программа Python завершает работу, как только обнаруживает необработанную ошибку. Эти ошибки можно разделить на два класса: 9SyntaxError: недопустимый синтаксис
Как показано в примере, стрелка указывает, где синтаксический анализатор столкнулся с синтаксической ошибкой.
Здесь мы можем заметить, что двоеточие :
отсутствует в операторе if
.
Логические ошибки Python (исключения)
Ошибки, возникающие во время выполнения (после прохождения синтаксического теста), называются исключениями или логическими ошибками .
Например, они возникают, когда мы пытаемся открыть несуществующий файл (для чтения) ( FileNotFoundError
), попробуйте разделить число на ноль ( ZeroDivisionError
) или попробуйте импортировать несуществующий модуль ( ImportError
).
Всякий раз, когда возникают такие ошибки во время выполнения, Python создает объект исключения. При неправильной обработке он выводит трассировку этой ошибки вместе с некоторыми подробностями о том, почему эта ошибка произошла.
Давайте посмотрим, как Python обрабатывает эти ошибки:
>>> 1 / 0 Traceback (последний последний вызов): Файл "<строка>", строка 301, в коде запуска Файл "<интерактивный ввод>", строка 1, в <модуль> ZeroDivisionError: деление на ноль >>> открыть("imaginary.txt") Traceback (последний последний вызов): Файл "<строка>", строка 301, в коде запуска Файл "<интерактивный ввод>", строка 1, в <модуль> FileNotFoundError: [Errno 2] Нет такого файла или каталога: 'imaginary.txt'
Встроенные исключения Python
Недопустимые операции могут вызывать исключения. В Python есть множество встроенных исключений, которые вызываются при возникновении соответствующих ошибок. Мы можем просмотреть все встроенные исключения с помощью встроенной функции local()
следующим образом: вернет модуль встроенных исключений, функций и атрибутов. dir
позволяет перечислить эти атрибуты в виде строк.
Некоторые из распространенных встроенных исключений в программировании на Python вместе с ошибками, которые их вызывают, перечислены ниже:
Исключение | Причина ошибки |
---|---|
Ошибка утверждения | Возникает при сбое оператора assert . |
Ошибка атрибута | Возникает при сбое назначения атрибута или ссылки. |
EOFError | Возникает, когда функция input() достигает конца файла. |
Ошибка плавающей точки | Возникает при сбое операции с плавающей запятой. |
ГенераторВыход | Повышение при вызове метода генератора close() . |
Ошибка импорта | Возникает, когда импортированный модуль не найден. |
Ошибка индекса | Возникает, когда индекс последовательности выходит за допустимые пределы. |
Ошибка ключа | Возникает, когда ключ не найден в словаре. |
Прерывание клавиатуры | Возникает, когда пользователь нажимает клавишу прерывания ( Ctrl+C или Delete ). |
Ошибка памяти | Возникает, когда операции не хватает памяти. |
Ошибка имени | Возникает, когда переменная не найдена в локальной или глобальной области видимости. |
Не реализованная ошибка | Выращен абстрактными методами. |
Ошибка ОС | Возникает, когда работа системы вызывает системную ошибку. |
Ошибка переполнения | Возникает, когда результат арифметической операции слишком велик для представления. |
Ошибка ссылки | Возникает, когда для доступа к референту со сборкой мусора используется прокси-сервер со слабой ссылкой. |
Ошибка выполнения | Возникает, когда ошибка не подпадает ни под какую другую категорию. |
StopIteration | Вызывается функцией next() , чтобы указать, что итератор больше не возвращает элемент. |
Синтаксическая ошибка | Вызывается синтаксическим анализатором при обнаружении синтаксической ошибки. |
Ошибка отступа | Возникает при неправильном отступе. |
TabError | Возникает, когда отступ состоит из несовместимых табуляций и пробелов. |
Системная ошибка | Возникает, когда интерпретатор обнаруживает внутреннюю ошибку. |
Выход из системы | Вызывается функцией sys. exit() . |
Ошибка типа | Возникает, когда функция или операция применяется к объекту неправильного типа. |
UnboundLocalError | Возникает, когда делается ссылка на локальную переменную в функции или методе, но к этой переменной не привязано ни одно значение. |
Ошибка Юникода | Возникает при возникновении ошибки кодирования или декодирования, связанной с Unicode. |
UnicodeEncodeError | Возникает, когда во время кодирования возникает ошибка, связанная с Unicode. |
UnicodeDecodeError | Возникает, когда во время декодирования возникает ошибка, связанная с Unicode. |
UnicodeTranslateError | Возникает, когда во время перевода возникает ошибка, связанная с Unicode. |
Ошибка значения | Возникает, когда функция получает аргумент правильного типа, но неправильное значение. |
ZeroDivisionError | Возникает, когда второй операнд деления или операции по модулю равен нулю. |
При необходимости мы также можем определить собственные исключения в Python. Чтобы узнать о них больше, посетите страницу Пользовательские исключения Python.
Мы можем обрабатывать эти встроенные и определяемые пользователем исключения в Python, используя попробуйте
, кроме
и наконец
операторов. Чтобы узнать о них больше, посетите Python операторы try, кроме и finally.
Содержание
Обработка исключений Python с использованием операторов try, exclude и finally
В этом руководстве вы узнаете, как обрабатывать исключения в вашей программе Python, используя операторы try, exclude и finally с помощью примеров.
Исключения в Python
Python имеет множество встроенных исключений, которые вызываются, когда ваша программа сталкивается с ошибкой (что-то в программе идет не так).
При возникновении этих исключений интерпретатор Python останавливает текущий процесс и передает его вызывающему процессу до тех пор, пока он не будет обработан. Если не обрабатывать, программа рухнет.
Например, давайте рассмотрим программу, в которой у нас есть функция A
, которая вызывает функцию B
, которая, в свою очередь, вызывает функцию C
. Если исключение возникает в функции C
, но не обрабатывается в C
, исключение передается в B
, а затем в А
.
Если никогда не обрабатываться, отображается сообщение об ошибке, и наша программа неожиданно останавливается.
Перехват исключений в Python
В Python исключения можно обрабатывать с помощью инструкции try
.
Критическая операция, которая может вызвать исключение, помещается в предложение try
. Код, обрабатывающий исключения, написан в разделе , кроме
.
Таким образом, мы можем выбрать, какие операции выполнять после того, как поймаем исключение. Вот простой пример.
# импортировать модуль sys, чтобы получить тип исключения импорт системы случайный список = ['а', 0, 2] для записи в randomList: пытаться: print("Запись есть", запись) г = 1/инт (запись) ломать кроме: print("Ой!", sys.exc_info()[0], "произошло.") print("Следующая запись") Распечатать() print("Обратное значение", запись, "равно", r)
Вывод
Запись является Ой! Произошел <класс 'ValueError'>. Следующая запись. Запись 0 Ой! Произошел <класс 'ZeroDivisionError'>. Следующая запись. Запись 2 Обратная величина 2 равна 0,5
В этой программе мы перебираем значения списка randomList . Как упоминалось ранее, часть, которая может вызвать исключение, помещается в блок try
.
Если исключения не возникает, блок , кроме
, пропускается и продолжается нормальный поток (для последнего значения). Но если возникает какое-либо исключение, оно перехватывается блоком , кроме
(первое и второе значения).
Здесь мы печатаем имя исключения, используя функция exc_info()
внутри модуля sys
. Мы видим, что a
вызывает ValueError
, а 0
вызывает ZeroDivisionError
.
Поскольку каждое исключение в Python наследуется от базового класса Exception
, мы также можем выполнить указанную выше задачу следующим образом:
# import module sys для получения типа исключения импорт системы случайный список = ['а', 0, 2] для записи в randomList: пытаться: print("Запись есть", запись) г = 1/инт (запись) ломать кроме Исключения как e: print("Ой!", e.__class__, "произошло.") print("Следующая запись") Распечатать() print("Обратное значение", entry, "is", r)
Эта программа имеет тот же результат, что и предыдущая программа.
Перехват определенных исключений в Python
В приведенном выше примере мы не упомянули никаких конкретных исключений в пункте , кроме
.
Это не очень хорошая практика программирования, поскольку она будет перехватывать все исключения и обрабатывать каждый случай одинаково. Мы можем указать, какие исключения должно перехватывать предложение , кроме
.
Предложение try
может иметь любое число , за исключением предложений
для обработки различных исключений, однако в случае возникновения исключения будет выполнено только одно.
Мы можем использовать кортеж значений, чтобы указать несколько исключений в предложении исключения. Вот пример псевдокода.
попытка: # сделай что-нибудь проходить кроме ValueError: # обработка исключения ValueError проходить кроме (TypeError, ZeroDivisionError): # обрабатывать несколько исключений # TypeError и ZeroDivisionError проходить кроме: # обрабатывать все остальные исключения пройти
Вызов исключений в Python
В программировании на Python исключения возникают при возникновении ошибок во время выполнения. Мы также можем вручную вызывать исключения, используя ключевое слово raise
.
При желании мы можем передать значения исключению, чтобы уточнить, почему это исключение было вызвано.
>>> поднять прерывание клавиатуры Traceback (последний последний вызов): ... КлавиатураПрерывание >>> поднять MemoryError("Это аргумент") Traceback (последний последний вызов): ... MemoryError: это аргумент >>> попробуйте: ... a = int(input("Введите положительное целое число:")) ... если а <= 0: ... поднять ValueError("Это не положительное число!") ... кроме ValueError как ve: ... печать (ve) ... Введите положительное целое число: -2 Это не положительное число!
Python try с предложением else
В некоторых ситуациях вам может понадобиться запустить определенный блок кода, если блок кода внутри try
выполняется без ошибок. В этих случаях вы можете использовать необязательное ключевое слово else
с оператором try
.
Примечание : Исключения в предложении else не обрабатываются предыдущими предложениями exclude.
Рассмотрим пример:
# программа для вывода обратного числа четных чисел пытаться: num = int(input("Введите число:")) утверждать число % 2 == 0 кроме: print("Нечетное число!") еще: обратное = 1/число печать (обратная)
Вывод
Если мы передаем нечетное число:
Введите число: 1 Не четное число!
Если мы передаем четное число, вычисляется и отображается обратное значение.
Введите число: 4 0.25
Однако, если мы передаем 0, мы получаем ZeroDivisionError
, поскольку блок кода внутри иначе
не обрабатывается предыдущим , кроме
.
Введите число: 0 Traceback (последний последний вызов): Файл "", строка 7, в обратное = 1/число ZeroDivisionError: деление на ноль
Python try.
..finally Оператор try
в Python может иметь необязательное предложение finally
. Это предложение выполняется несмотря ни на что и обычно используется для освобождения внешних ресурсов.
Например, мы можем быть подключены к удаленному центру обработки данных через сеть или работать с файлом или графическим интерфейсом пользователя (GUI).
Во всех этих случаях мы должны очистить ресурс до того, как программа остановится, независимо от того, успешно она работала или нет. Эти действия (закрытие файла, GUI или отключение от сети) выполняются в , наконец, пункт
, гарантирующий исполнение.
Вот пример операций с файлами, иллюстрирующий это.
попытка: f = открыть ("test.txt", кодировка = 'utf-8') # выполняем файловые операции в конце концов: f.close()
Этот тип конструкции гарантирует, что файл будет закрыт, даже если во время выполнения программы возникнет исключение.
Python Попробуйте, кроме
❮ Предыдущий Далее ❯
Блок try
позволяет протестировать
блок кода ошибок.
Блок , кроме
, позволяет
справиться с ошибкой.
Блок else
позволяет
выполнить код, когда нет ошибки.
Блок finally
позволяет
выполнять код независимо от результата блоков try- и exclude.
Обработка исключений
Когда возникает ошибка или исключение, как мы его называем, Python обычно останавливается и генерировать сообщение об ошибке.
Эти исключения можно обработать с помощью try
оператор:
Пример
Блок try
создаст исключение,
поскольку x
не определено:
try:
print(x)
exclude:
print("Произошло исключение")
Попробуйте сами »
Поскольку блок try вызывает ошибку, блок exclude будет казнен.
Без блока try программа завершится с ошибкой:
Пример
Этот оператор вызовет ошибку,
потому что x
не определено:
print(x)
Попробуйте сами »
Множество исключений
Вы можете определить столько блоков исключений, сколько захотите, например, если вы хотите выполнить специальный блок кода для особого вида ошибки:
Пример
Печатать одно сообщение, если блок try вызывает NameError
и другое
для других ошибок:
попробуйте:
print(x)
, кроме NameError:
print("Переменная x
не определено")
кроме:
print("Что-то еще пошло
неправильно")
Попробуйте сами »
Else
Вы можете использовать ключевое слово else
для определения
блок кода, который должен быть выполнен, если ошибок не возникло:
Пример
В этом примере блок try
не
генерировать любую ошибку:
попробовать:
print("Привет")
кроме:
print("Что-то пошло
неправильно")
else:
print("Все пошло не так")
Попробуйте сами »
finally
Блок finally
, если он указан, будет выполнен
независимо от того, блокирует ли попытка
выдает ошибку или нет.
Пример
try:
print(x)
exclude:
print("Что-то пошло
неправильно")
finally:
print("Попытка исключения завершена")
Попробуйте сами »
Это может быть полезно для закрытия объектов и очистки ресурсов:
Пример
Попробуйте открыть и записать в файл, недоступный для записи:
попытка:
f = open("demofile.txt")
попытка:
f.write("Lorum Ipsum")
кроме:
print("Что-то пошло не так при записи в файл")
finally:
f.close()
кроме:
print("Что-то пошло не так при открытии
file")
Попробуйте сами »
Программа может продолжать работу, не оставляя файловый объект открытым.0006
Чтобы сгенерировать (или вызвать) исключение, используйте ключевое слово raise
.
Пример
Выдать ошибку и остановить программу, если x меньше 0:
x = -1
, если x < 0:
поднять Exception("Извините, ниже нет чисел
нуля")
Попробуйте сами »
Ключевое слово raise
используется для повышения
исключение.
Вы можете определить, какую ошибку выдавать и какой текст печатать пользователю.
Пример
Выдать TypeError, если x не является целым числом:
x = "hello"
если не type(x) is int:
поднять TypeError("Только
разрешены целые числа")
Попробуйте сами »
❮ Предыдущая Далее ❯
НОВИНКА
Мы только что запустили
Видео W3Schools
Узнать
ВЫБОР ЦВЕТА
КОД ИГРЫ
Играть в игру
Top Tutorials
Учебник по HTMLУчебник CSS
Учебник JavaScript
How To Tutorial
Учебник SQL
Учебник Python
Учебник W3.CSS
Учебник Bootstrap
Учебник PHP
Учебник Java
Учебник C++
Учебник jQuery
Tops 910
Справочник по HTML
Справочник по CSS
Справочник по JavaScript
Справочник по SQL
Справочник по Python
Справочник по W3. CSS
Справочник по Bootstrap
Справочник по PHP
Цвета HTML
Справочник по Java
Справочник по Angular
Справочник по jQuery
Основные примеры
Примеры HTMLПримеры CSS
Примеры JavaScript
Примеры инструкций
Примеры SQL
Примеры Python
Примеры W3.CSS
Примеры Bootstrap
Примеры PHP
Примеры Java
Примеры XML
Примеры jQuery
FORUM | О
W3Schools оптимизирован для обучения и обучения. Примеры могут быть упрощены для улучшения чтения и обучения. Учебники, ссылки и примеры постоянно пересматриваются, чтобы избежать ошибок, но мы не можем гарантировать полную правильность всего содержания. Используя W3Schools, вы соглашаетесь прочитать и принять наши условия использования, куки-файлы и политика конфиденциальности.
Copyright 1999-2022 Refsnes Data. Все права защищены.
W3Schools использует W3. SyntaxError: неверный синтаксис 9 . Обратите также внимание на то, что последующая строка print(1)
не была выполнена, так как интерпретатор Python перестал работать, когда произошла ошибка.
Давайте исправим эту ошибку и перезапустим код:
печать(х) печать(1)
-------------------------------------------------- -------------------------- NameError Traceback (последний последний вызов) ~\AppData\Local\Temp/ipykernel_4732/971139432.py в ----> 1 отпечаток (х) 2 принт(1) NameError: имя «x» не определено
Теперь, когда мы исправили неправильный синтаксис, мы получили другой тип ошибки: исключение. Другими словами, исключение — это тип ошибки, возникающий, когда синтаксически правильный код Python вызывает ошибку . Стрелка указывает строку, в которой произошло исключение, а последняя строка сообщения об ошибке указывает точный тип исключения и предоставляет его описание для облегчения отладки. В нашем случае это NameError
, так как мы пытались вывести значение переменной x
, который не был определен ранее. Также в этом случае вторая строка нашего фрагмента кода print(1)
не была выполнена, потому что нормальный ход программы Python был прерван.
Чтобы предотвратить внезапный сбой программы, важно перехватывать и обрабатывать исключения. Например, предоставьте альтернативную версию выполнения кода при возникновении данного исключения. Этому мы и будем учиться дальше.
Стандартные встроенные типы исключений
Python предоставляет множество типов исключений, создаваемых в различных ситуациях. Давайте рассмотрим наиболее распространенные встроенные исключения с их примерами:
-
NameError
— Возникает, когда имя не существует ни среди локальных, ни среди глобальных переменных:
печать(х)
-------------------------------------------------- -------------------------- NameError Traceback (последний последний вызов) ~\AppData\Local\Temp/ipykernel_4732/1353120783.py в ----> 1 отпечаток (х) NameError: имя «x» не определено
-
TypeError
— возникает, когда операция выполняется с неприменимым типом данных: 902:30
печать(1+'1')
-------------------------------------------------- -------------------------- TypeError Traceback (последний последний вызов) ~\AppData\Local\Temp/ipykernel_4732/218464413. py в ----> 1 отпечаток (1+'1') TypeError: неподдерживаемые типы операндов для +: 'int' и 'str'
-
ValueError
— Возникает, когда операция или функция принимает недопустимое значение аргумента:
печать (целое ('а'))
-------------------------------------------------- -------------------------- ValueError Traceback (последний последний вызов) ~\AppData\Local\Temp/ipykernel_4732/3219923713.py в ----> 1 печать (целое ('a')) ValueError: неверный литерал для int() с основанием 10: 'a'
-
IndexError
— возникает, когда индекс не существует в итерируемом объекте:
печать('собака'[3])
-------------------------------------------------- -------------------------- IndexError Traceback (последний последний вызов) ~\AppData\Local\Temp/ipykernel_4732/2163152480.py в ----> 1 печать('собака'[3]) IndexError: индекс строки вне диапазона 9IndentationError: ожидается блок с отступом
-
ZeroDivisionError
— Возникает при попытке деления числа на ноль:
печать(1/0)
-------------------------------------------------- -------------------------- ZeroDivisionError Traceback (последний последний вызов) ~\AppData\Local\Temp/ipykernel_4732/165659023. py в ----> 1 отпечаток (1/0) ZeroDivisionError: деление на ноль
-
Ошибка импорта
— Возникает, когда оператор импорта неверен:
из numpy import pandas
-------------------------------------------------- -------------------------- ImportError Traceback (последний последний вызов) ~\AppData\Local\Temp/ipykernel_4732/3955928270.py в ----> 1 из numpy import pandas ImportError: невозможно импортировать имя «панды» из «numpy» (C:\Users\Utente\anaconda3\lib\site-packages\numpy\__init__.py)
-
AttributeError
— Возникает при попытке назначить или сослаться на атрибут, неприменимый для данного объекта Python:
печать('а'.сумма())
-------------------------------------------------- -------------------------- AttributeError Traceback (последний последний вызов) ~\AppData\Local\Temp/ipykernel_4732/2316121794.py в ----> 1 print('a'.sum()) AttributeError: объект «str» не имеет атрибута «сумма»
-
KeyError
— Возникает при отсутствии ключа в словаре:
животных = {'коала': 1, 'панда': 2} печать (животные ['кролик'])
-------------------------------------------------- -------------------------- KeyError Traceback (последний последний вызов) ~\AppData\Local\Temp/ipykernel_4732/1340951462. py в 1 животное = {'коала': 1, 'панда': 2} ----> 2 print(животные['кролик']) KeyError: «кролик»
Полный список встроенных исключений Python см. в документации по Python.
Обработка исключений в Python
Поскольку возбуждение исключения приводит к прерыванию выполнения программы, мы должны обработать это исключение заранее, чтобы избежать таких нежелательных случаев.
попробовать
и , кроме операторов
Самые основные команды, используемые для обнаружения и обработки исключений в Python: try
и , кроме
.
Оператор try
используется для запуска фрагмента кода, подверженного ошибкам, и за ним всегда должен следовать оператор 9.0026, кроме оператора . Если в результате выполнения блока try
не возникает никаких исключений, блок , кроме
, пропускается, и программа просто работает, как ожидалось. В противоположном случае, если возникает исключение, выполнение блока try
немедленно останавливается, и программа обрабатывает возникшее исключение, выполняя альтернативный код, определенный в блоке , кроме
. После этого скрипт Python продолжает работу и выполняет остальной код.
Давайте посмотрим, как это работает на примере нашего исходного небольшого фрагмента кода print(x)
, который ранее вызывал NameError
:
попробуйте: печать (х) кроме: print('Сначала объявите переменную x') печать(1)
Сначала объявите переменную x 1
Теперь, когда мы обработали исключение в блоке , кроме
, мы получили значимое индивидуальное сообщение о том, что именно пошло не так и как это исправить. Более того, на этот раз программа не прекратила работу, как только столкнулась с исключением и выполнила остальную часть кода.
В приведенном выше случае мы ожидали и обработали только один тип исключения, а именно NameError
. Недостатком этого подхода является то, что фрагмент кода в предложении , кроме
, будет обрабатывать все типы исключений одинаково и выводить одно и то же сообщение Пожалуйста, сначала объявите переменную x
. Чтобы избежать этой путаницы, мы можем явно указать тип исключения, которое нам нужно поймать и обработать сразу после , кроме 9.0027 команда:
попробуйте: печать (х) кроме NameError: print('Сначала объявите переменную x')
Сначала объявите переменную x
Обработка нескольких исключений
Четкое указание типа перехватываемого исключения необходимо не только для удобочитаемости кода. Что еще более важно, используя этот подход, мы можем предвидеть различные конкретные исключения и обрабатывать их соответствующим образом.
Чтобы понять эту концепцию, давайте взглянем на простую функцию, которая суммирует значения входного словаря:
по определению print_dict_sum(dct): печать (сумма (dct.значения ())) my_dict = {'а': 1, 'б': 2, 'с': 3} print_dict_sum(my_dict)
6
При попытке запустить эту функцию у нас могут возникнуть разные проблемы, если мы случайно передадим ей неверный ввод. Например, мы можем сделать ошибку в имени словаря, что приведет к несуществующей переменной:
.print_dict_sum(mydict)
-------------------------------------------------- -------------------------- NameError Traceback (последний последний вызов) ~\AppData\Local\Temp/ipykernel_4732/2473187932.py в ----> 1 print_dict_sum(mydict) NameError: имя «mydict» не определено
Некоторые значения входного словаря могут быть строковыми, а не числовыми:
my_dict = {'а': '1', 'б': 2, 'с': 3} print_dict_sum(my_dict)
-------------------------------------------------- -------------------------- TypeError Traceback (последний последний вызов) ~\AppData\Local\Temp/ipykernel_4732/2621846538.py в 1 my_dict = {'а': '1', 'б': 2, 'с': 3} ----> 2 print_dict_sum(my_dict) ~\AppData\Local\Temp/ipykernel_4732/3241128871.py в print_dict_sum(dct) 1 определение print_dict_sum(dct): ----> 2 print(sum(dct.values())) 3 4 my_dict = {'а': 1, 'б': 2, 'с': 3} 5 print_dict_sum(my_dict) TypeError: неподдерживаемые типы операндов для +: 'int' и 'str'
Другой вариант позволяет нам передать аргумент неподходящего типа данных для этой функции:
my_dict = 'а' print_dict_sum(my_dict)
-------------------------------------------------- -------------------------- AttributeError Traceback (последний последний вызов) ~\AppData\Local\Temp/ipykernel_4732/1925769844. py в 1 мой_дикт = 'а' ----> 2 print_dict_sum(my_dict) ~\AppData\Local\Temp/ipykernel_4732/3241128871.py в print_dict_sum(dct) 1 определение print_dict_sum(dct): ----> 2 print(sum(dct.values())) 3 4 my_dict = {'а': 1, 'б': 2, 'с': 3} 5 print_dict_sum(my_dict) AttributeError: объект «str» не имеет атрибута «значения»
В результате у нас есть как минимум три различных типа исключений, которые следует обрабатывать по-разному: NameError
, TypeError
и AttributeError
. Для этого мы можем добавить несколько блоков , кроме
(по одному для каждого типа исключения, три в нашем случае) после одного блока try
:
попробуйте: print_dict_sum(mydict) кроме NameError: print('Пожалуйста, проверьте правильность написания имени словаря') кроме TypeError: print('Похоже, что некоторые значения словаря не являются числовыми') кроме AttributeError: print('Вы должны предоставить словарь Python с числовыми значениями')
Пожалуйста, проверьте написание имени словаря
В приведенном выше коде мы предоставили несуществующее имя переменной в качестве входных данных для функции внутри предложения try
. Код должен был выдать NameError
, но он был обработан в одном из последующих кроме
предложений, и было выведено соответствующее сообщение.
Мы также можем обрабатывать исключения прямо внутри определения функции. Важно: Мы не можем справиться с NameError
исключение для любого из аргументов функции, так как в этом случае исключение возникает до запуска тела функции. Например, в коде ниже:
по определению print_dict_sum(dct): пытаться: печать (сумма (dct.значения ())) кроме NameError: print('Пожалуйста, проверьте правильность написания имени словаря') кроме TypeError: print('Похоже, что некоторые значения словаря не являются числовыми') кроме AttributeError: print('Вы должны предоставить словарь Python с числовыми значениями') print_dict_sum({'a': '1', 'b': 2, 'c': 3}) print_dict_sum('а') print_dict_sum(mydict)
Кажется, что некоторые значения словаря не являются числовыми Вы должны предоставить словарь Python с числовыми значениями -------------------------------------------------- ------------------------- NameError Traceback (последний последний вызов) ~\AppData\Local\Temp/ipykernel_4732/3201242278. py в 11 print_dict_sum({'a': '1', 'b': 2, 'c': 3}) 12 print_dict_sum('а') ---> 13 print_dict_sum(mydict) NameError: имя «mydict» не определено
TypeError
и AttributeError
были успешно обработаны внутри функции, и были выведены соответствующие сообщения. Вместо этого, по вышеупомянутой причине, ошибка NameError
не была обработана должным образом, несмотря на то, что для нее было введено отдельное предложение , кроме
. Таким образом, ошибка NameError
для любого аргумента функции не может быть обработана внутри тела функции .
Можно объединить несколько исключений как кортеж в один , за исключением пункта
, если с ними следует обращаться одинаково:
по определению print_dict_sum(dct): пытаться: печать (сумма (dct.значения ())) кроме (TypeError, AttributeError): print('Вы должны предоставить СЛОВАРЬ Python с ЦИФРОВЫМИ значениями') print_dict_sum({'a': '1', 'b': 2, 'c': 3}) print_dict_sum('а')
Вы должны предоставить СЛОВАРЬ Python с ЦИФРОВЫМИ значениями Вы должны предоставить СЛОВАРЬ Python с ЦИФРОВЫМИ значениями
еще
Заявление В дополнение к предложениям try
и , кроме
, мы можем использовать необязательную команду else
. Если присутствует, команда else
должна быть помещена после всех предложений , кроме
, и выполняться только в том случае, если в предложении try
не возникло исключений.
Например, в приведенном ниже коде мы попробовали деление на ноль:
попробуйте: печать(3/0) кроме ZeroDivisionError: print('Нельзя делить на ноль') еще: print('Деление успешно выполнено')
Нельзя делить на ноль
Исключение было перехвачено и обработано в блоке , кроме
, поэтому предложение else
было пропущено. Давайте посмотрим, что произойдет, если мы укажем ненулевое число:
попробуйте: печать(3/2) кроме ZeroDivisionError: print('Нельзя делить на ноль') еще: print('Деление успешно выполнено')
1,5 Деление успешно выполнено
Поскольку исключения не возникало, иначе
блок был выполнен и выдал соответствующее сообщение.
Наконец,
Заявление Другим необязательным оператором является finally
, если он предоставлен, он должен быть помещен после всех предложений, включая else
(если присутствует)
, и выполняться в любом случае, независимо от того, было ли возбуждено исключение в предложении try
.
Давайте добавим блок finally
к обоим предыдущим фрагментам кода и посмотрим на результат:
попробуйте: печать(3/0) кроме ZeroDivisionError: print('Нельзя делить на ноль') еще: print('Деление успешно выполнено') в конце концов: print('Это сообщение всегда печатается')
Нельзя делить на ноль Это сообщение всегда печатается
попробуйте: печать(3/2) кроме ZeroDivisionError: print('Нельзя делить на ноль') еще: print('Деление успешно выполнено') в конце концов: print('Это сообщение всегда печатается')
1,5 Деление успешно выполнено Это сообщение всегда печатается
В первом случае было возбуждено исключение, во втором - нет. Однако в обоих случаях предложение finally
выводит одно и то же сообщение.
Вызов исключения
Иногда нам может потребоваться намеренно вызвать исключение и остановить программу при возникновении определенного условия. Для этого нам понадобится ключевое слово поднять
и следующий синтаксис:
поднять ExceptionClass(exception_value)
Выше, Исключение Класс
— это тип возбуждаемого исключения (например, TypeError
), а exception_value
— это необязательное настраиваемое описательное сообщение, которое будет отображаться при возникновении исключения.
Давайте посмотрим, как это работает:
х = «синий» если x не в ['красном', 'желтом', 'зеленом']: поднять ValueError
-------------------------------------------------- -------------------------- ValueError Traceback (последний последний вызов) ~\AppData\Local\Temp/ipykernel_4732/2843707178.py в 1 х = «синий» 2, если x не входит в ['красный', 'желтый', 'зеленый']: ----> 3 поднять ValueError ЗначениеОшибка:
В приведенном выше фрагменте кода мы не предоставили никакого аргумента исключению, поэтому код не вывел никакого сообщения (по умолчанию значение исключения равно None
).
х = «синий» если x не в ['красном', 'желтом', 'зеленом']: поднять ValueError('Светофор не работает')
-------------------------------------------------- -------------------------- ValueError Traceback (последний последний вызов) ~\AppData\Local\Temp/ipykernel_4732/359420707.py в 1 х = «синий» 2, если x не входит в ['красный', 'желтый', 'зеленый']: ----> 3 поднять ValueError('Светофор не работает') ValueError: Светофор не работает
Мы запустили тот же фрагмент кода, но на этот раз мы предоставили аргумент исключения. В этом случае мы можем увидеть выходное сообщение, которое дает больше контекста, почему именно это исключение произошло.
Заключение
В этом руководстве мы обсудили многие аспекты исключений в Python. В частности, мы узнали следующее:
- Как определить исключения в Python и чем они отличаются от синтаксических ошибок
- Какие встроенные исключения существуют в Python и когда они вызываются
- Почему важно перехватывать и обрабатывать исключения
- Как обрабатывать одно или несколько исключений в Python
- Как разные предложения для перехвата и обработки исключений работают вместе
- Почему важно указать тип обрабатываемого исключения
- Почему мы не можем справиться с
NameError
для любого аргумента функции внутри определения функции - Как вызвать исключение
- Как добавить описательное сообщение к возникшему исключению и почему это рекомендуется
Обладая этими навыками, вы готовы справиться с любыми реальными задачами по обработке данных, требующими разрешения исключений в Python.
Учебное пособие по Pythonpython
Об авторе
Елена Косоурова
Елена — геолог-нефтяник и менеджер сообщества Dataquest. Вы можете найти ее в чате онлайн с энтузиастами данных и в написании руководств по темам науки о данных. Найдите ее в LinkedIn.
Ошибки и исключения в Python
Просмотреть обсуждение
Улучшить статью
Сохранить статью
- Уровень сложности: Easy
- Последнее обновление: 22 окт, 2021
Посмотреть обсуждение
Улучшить статью
Сохранить статью
Ошибки — это проблемы в программе, из-за которых программа останавливает выполнение. С другой стороны, исключения возникают, когда происходят некоторые внутренние события, которые изменяют нормальный ход программы.
В python возникает два типа ошибок.
- Синтаксические ошибки
- Логические ошибки (исключения)
Синтаксические ошибки
Если не соблюдается правильный синтаксис языка, возникает синтаксическая ошибка.
Example
Python3
|
Output:
Возвращает сообщение об ошибке синтаксиса, так как после оператора if отсутствует двоеточие:. Мы можем исправить это, написав правильный синтаксис.
логические ошибки (исключение)
Во время выполнения ошибка, возникающая после прохождения синтаксического теста, называется исключением или логическим типом. Например, когда мы делим любое число на ноль, возникает исключение ZeroDivisionError, или когда мы импортируем несуществующий модуль, возникает ошибка ImportError.
Example 1:
Python3
|
Вывод:
В приведенном выше примере ZeroDivisionError, поскольку мы пытаемся разделить число на 0.
Пример 2: Неправильный отступ.
Python3
|
Output:
Некоторые из общих встроенных исключений, кроме упомянутых выше исключений:
Исключение | Описание |
---|---|
IndexError | При получении неверного индекса списка. |
AssertionError | Возникает при сбое оператора assert |
AttributeError | Возникает при сбое присвоения атрибута. |
ImportError | Это происходит, когда импортированный модуль не найден. |
Ошибка ключа | Возникает, когда ключ словаря не найден. |
NameError | Это происходит, когда переменная не определена. |
MemoryError | Это происходит, когда программе не хватает памяти. |
TypeError | Это происходит, когда функция и операция применяются в неверном типе. |
Примечание. Дополнительные сведения см. в разделе Встроенные исключения в Python
Обработка ошибок
Когда возникает ошибка или исключение, мы обрабатываем это с помощью метода Handling.
- Обработка исключений с помощью Try/Except/Finally
Мы можем обрабатывать ошибки с помощью метода Try/Except/Finally. мы пишем небезопасный код в блоке try, резервный код в блоке exclude и окончательный код в блоке finally.
Пример
Python3
|
- Output:
code start возникает ошибка GeeksForGeeks
- Вызов исключений для предопределенного условия
Когда мы хотим закодировать ограничение определенных условий, мы можем вызвать исключение.
Example
Python3
|