Документация Python неофициальный перевод

errors.md

312 строк · 25.7 КБ · обычная страница · сырой текст · скачать

1> **Источник:** https://python-all.ru/2.7/tutorial/errors.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# 8. Ошибки и исключения89До сих пор мы лишь упоминали сообщения об ошибках, но если вы пробовали примеры, то, скорее всего, уже с ними сталкивались. Существует (как минимум) два различимых вида ошибок: *синтаксические ошибки* и *исключения*.1011## 8.1. Синтаксические ошибки1213Синтаксические ошибки, также известные как ошибки разбора, – пожалуй, самый распространённый вид неполадок, с которыми вы сталкиваетесь, пока учите Python:1415```python16>>> while True print 'Hello world'17  File "<stdin>", line 118    while True print 'Hello world'19                   ^20SyntaxError: invalid syntax21```2223Парсер повторяет строку с ошибкой и отображает маленькую стрелку, указывающую на самое раннее место в строке, где была обнаружена ошибка. Ошибка вызывается (или по крайней мере обнаруживается) токеном, *предшествующим* стрелке: в примере ошибка обнаруживается в ключевом слове [`print`](https://python-all.ru/2.7/reference/simple_stmts.html#print), поскольку перед ним отсутствует двоеточие (`':'`). Имя файла и номер строки выводятся, чтобы было понятно, куда смотреть, если входные данные поступили из скрипта.2425## 8.2. Исключения2627Даже если оператор или выражение синтаксически верны, при попытке его выполнения может возникнуть ошибка. Ошибки, обнаруженные во время выполнения, называются *исключениями* и не являются безусловно фатальными: вы скоро научитесь обрабатывать их в программах на Python. Однако большинство исключений не обрабатываются программами и приводят к сообщениям об ошибках, как показано ниже:2829```python30>>> 10 * (1/0)31Traceback (most recent call last):32  File "<stdin>", line 1, in <module>33ZeroDivisionError: integer division or modulo by zero34>>> 4 + spam*335Traceback (most recent call last):36  File "<stdin>", line 1, in <module>37NameError: name 'spam' is not defined38>>> '2' + 239Traceback (most recent call last):40  File "<stdin>", line 1, in <module>41TypeError: cannot concatenate 'str' and 'int' objects42```4344Последняя строка сообщения об ошибке показывает, что произошло. Исключения бывают разных типов, и тип выводится как часть сообщения: в примере это [`ZeroDivisionError`](https://python-all.ru/2.7/library/exceptions.html#exceptions.ZeroDivisionError), [`NameError`](https://python-all.ru/2.7/library/exceptions.html#exceptions.NameError) и [`TypeError`](https://python-all.ru/2.7/library/exceptions.html#exceptions.TypeError). Строка, выводимая как тип исключения, – это имя встроенного исключения, которое произошло. Это верно для всех встроенных исключений, но не обязательно для определяемых пользователем (хотя это полезное соглашение). Стандартные имена исключений – встроенные идентификаторы (не зарезервированные ключевые слова).4546Остальная часть строки содержит подробности в зависимости от типа исключения и того, что его вызвало.4748Предыдущая часть сообщения об ошибке показывает контекст, в котором произошло исключение, в виде трассировки стека. Обычно она содержит трассировку стека с перечислением строк исходного кода; однако строки, прочитанные из стандартного ввода, отображаться не будут.4950[Встроенные исключения](https://python-all.ru/2.7/library/exceptions.html#bltin-exceptions) содержит список встроенных исключений и их значение.5152## 8.3. Обработка исключений5354Можно писать программы, обрабатывающие выбранные исключения. В следующем примере показан запрос ввода у пользователя до тех пор, пока не будет введено целое число, но при этом пользователь может прервать программу (с помощью `Control-C` или того, что поддерживает операционная система); обратите внимание, что прерывание пользователем вызывает исключение [`KeyboardInterrupt`](https://python-all.ru/2.7/library/exceptions.html#exceptions.KeyboardInterrupt).5556```python57>>> while True:58...     try:59...         x = int(raw_input("Please enter a number: "))60...         break61...     except ValueError:62...         print "Oops!  That was no valid number.  Try again..."63...64```6566Инструкция [`try`](https://python-all.ru/2.7/reference/compound_stmts.html#try) работает следующим образом.6768- Сначала выполняется *try-блок* (инструкции между ключевыми словами [`try`](https://python-all.ru/2.7/reference/compound_stmts.html#try) и [`except`](https://python-all.ru/2.7/reference/compound_stmts.html#except)).69- Если исключение не произошло, *except-блок* пропускается, и выполнение инструкции [`try`](https://python-all.ru/2.7/reference/compound_stmts.html#try) завершается.70- Если при выполнении блока try возникает исключение, оставшаяся часть блока пропускается. Затем, если его тип совпадает с исключением, указанным после [`except`](https://python-all.ru/2.7/reference/compound_stmts.html#except) ключевого слова, выполняется блок except, и затем выполнение продолжается после оператора [`try`](https://python-all.ru/2.7/reference/compound_stmts.html#try).71- Если возникает исключение, которое не соответствует исключению, указанному в блоке except, оно передается внешним операторам [`try`](https://python-all.ru/2.7/reference/compound_stmts.html#try); если обработчик не найден, это *необработанное исключение* и выполнение останавливается с сообщением, как показано выше.7273Оператор [`try`](https://python-all.ru/2.7/reference/compound_stmts.html#try) может содержать более одного блока except для указания обработчиков разных исключений. Будет выполнен не более одного обработчика. Обработчики обрабатывают только исключения, возникшие в соответствующем блоке try, а не в других обработчиках того же оператора [`try`](https://python-all.ru/2.7/reference/compound_stmts.html#try). Блок except может указывать несколько исключений в виде кортежа в скобках, например:7475```python76... except (RuntimeError, TypeError, NameError):77...     pass78```7980Обратите внимание, что круглые скобки вокруг этого кортежа обязательны, поскольку `except ValueError, e:` был синтаксисом, использовавшимся для того, что в современном Python обычно записывается как `except ValueError as e:` (описано ниже). Старый синтаксис всё ещё поддерживается для обратной совместимости. Это означает, что `except RuntimeError, TypeError` эквивалентно не `except (RuntimeError, TypeError):`, а `except RuntimeError as TypeError:`, что не то, что нужно.8182Последний блок except может опускать имена исключений, чтобы служить универсальным обработчиком. Используйте это с особой осторожностью, поскольку легко скрыть настоящую ошибку программирования таким образом! Его также можно использовать для вывода сообщения об ошибке и последующего повторного возбуждения исключения (позволяя вызывающему коду также обработать исключение):8384```python85import sys8687try:88    f = open('myfile.txt')89    s = f.readline()90    i = int(s.strip())91except IOError as e:92    print "I/O error({0}): {1}".format(e.errno, e.strerror)93except ValueError:94    print "Could not convert data to an integer."95except:96    print "Unexpected error:", sys.exc_info()[0]97    raise98```99100Оператор [`try`](https://python-all.ru/2.7/reference/compound_stmts.html#try) … [`except`](https://python-all.ru/2.7/reference/compound_stmts.html#except) имеет необязательную *часть else*, которая, если присутствует, должна следовать за всеми блоками except. Она полезна для кода, который должен быть выполнен, если блок try не вызвал исключение. Например:101102```python103for arg in sys.argv[1:]:104    try:105        f = open(arg, 'r')106    except IOError:107        print 'cannot open', arg108    else:109        print arg, 'has', len(f.readlines()), 'lines'110        f.close()111```112113Использование блока [`else`](https://python-all.ru/2.7/reference/compound_stmts.html#else) лучше, чем добавление дополнительного кода в блок [`try`](https://python-all.ru/2.7/reference/compound_stmts.html#try), поскольку это позволяет избежать случайного перехвата исключения, которое не было возбуждено кодом, защищённым инструкцией [`try`](https://python-all.ru/2.7/reference/compound_stmts.html#try) … [`except`](https://python-all.ru/2.7/reference/compound_stmts.html#except).114115Когда возникает исключение, оно может иметь связанное значение, также известное как *аргумент* исключения. Наличие и тип аргумента зависят от типа исключения.116117В предложении except можно указать переменную после имени исключения (или кортежа). Переменная привязывается к экземпляру исключения, аргументы которого хранятся в `instance.args`. Для удобства экземпляр исключения определяет [`__str__()`](https://python-all.ru/2.7/reference/datamodel.html#object.__str__), так что аргументы можно выводить напрямую, без обращения к `.args`.118119Также можно сначала создать экземпляр исключения, а затем возбудить его, добавив к нему любые атрибуты по желанию.120121```python122>>> try:123...     raise Exception('spam', 'eggs')124... except Exception as inst:125...     print type(inst)     # экземпляр исключения126...     print inst.args      # аргументы, хранящиеся в .args127...     print inst           # __str__ позволяет args выводиться напрямую128...     x, y = inst.args129...     print 'x =', x130...     print 'y =', y131...132<type 'exceptions.Exception'>133('spam', 'eggs')134('spam', 'eggs')135x = spam136y = eggs137```138139Если у исключения есть аргумент, он выводится как последняя часть («подробности») сообщения для необработанных исключений.140141Обработчики исключений обрабатывают исключения не только при их непосредственном возникновении в блоке try, но и если они возникают внутри функций, вызываемых (даже косвенно) в блоке try. Например:142143```python144>>> def this_fails():145...     x = 1/0146...147>>> try:148...     this_fails()149... except ZeroDivisionError as detail:150...     print 'Handling run-time error:', detail151...152Handling run-time error: integer division or modulo by zero153```154155## 8.4. Возбуждение исключений156157Инструкция [`raise`](https://python-all.ru/2.7/reference/simple_stmts.html#raise) позволяет программисту принудительно вызвать указанное исключение. Например:158159```python160>>> raise NameError('HiThere')161Traceback (most recent call last):162  File "<stdin>", line 1, in <module>163NameError: HiThere164```165166Единственный аргумент [`raise`](https://python-all.ru/2.7/reference/simple_stmts.html#raise) указывает возбуждаемое исключение. Это должен быть либо экземпляр исключения, либо класс исключения (класс, производный от `Exception`).167168Если нужно определить, было ли возбуждено исключение, но обрабатывать его не предполагается, более простая форма инструкции [`raise`](https://python-all.ru/2.7/reference/simple_stmts.html#raise) позволяет повторно возбудить исключение:169170```python171>>> try:172...     raise NameError('HiThere')173... except NameError:174...     print 'An exception flew by!'175...     raise176...177An exception flew by!178Traceback (most recent call last):179  File "<stdin>", line 2, in <module>180NameError: HiThere181```182183## 8.5. Определяемые пользователем исключения184185Программы могут определять собственные исключения, создавая новый класс исключения (см. [Классы](https://python-all.ru/2.7/tutorial/classes.html#tut-classes) для получения дополнительной информации о классах Python). Исключения обычно должны наследоваться от класса [`Exception`](https://python-all.ru/2.7/library/exceptions.html#exceptions.Exception), прямо или косвенно. Например:186187```python188>>> class MyError(Exception):189...     def __init__(self, value):190...         self.value = value191...     def __str__(self):192...         return repr(self.value)193...194>>> try:195...     raise MyError(2*2)196... except MyError as e:197...     print 'My exception occurred, value:', e.value198...199My exception occurred, value: 4200>>> raise MyError('oops!')201Traceback (most recent call last):202  File "<stdin>", line 1, in <module>203__main__.MyError: 'oops!'204```205206В этом примере стандартный [`__init__()`](https://python-all.ru/2.7/reference/datamodel.html#object.__init__) класса `Exception` был переопределён. Новое поведение просто создаёт атрибут *value*. Это заменяет стандартное поведение по созданию атрибута *args*.207208Классы исключений можно определять так же, как любые другие классы, но обычно их делают простыми, часто предоставляя лишь несколько атрибутов, позволяющих обработчикам исключений извлекать информацию об ошибке. При создании модуля, который может вызывать несколько различных ошибок, распространённой практикой является создание базового класса для исключений, определённых в этом модуле, и наследование от него для создания конкретных классов исключений для разных условий ошибок:209210```python211class Error(Exception):212    """Базовый класс для исключений в этом модуле."""213    pass214215class InputError(Error):216    """Исключение, возникающее при ошибках ввода.217218    Атрибуты:219        expr -- входное выражение, в котором произошла ошибка220        msg  -- объяснение ошибки221    """222223    def __init__(self, expr, msg):224        self.expr = expr225        self.msg = msg226227class TransitionError(Error):228    """Возникает, когда операция пытается выполнить переход состояния, который не229    разрешён.230231    Атрибуты:232        prev -- состояние в начале перехода233        next -- новое состояние, которое было запрошено234        msg  -- объяснение, почему данный переход не разрешён235    """236237    def __init__(self, prev, next, msg):238        self.prev = prev239        self.next = next240        self.msg = msg241```242243Большинство исключений имеют имена, оканчивающиеся на «Error», подобно именованию стандартных исключений.244245Многие стандартные модули определяют собственные исключения для сообщения об ошибках, которые могут возникнуть в определяемых ими функциях. Дополнительная информация о классах представлена в главе [Классы](https://python-all.ru/2.7/tutorial/classes.html#tut-classes).246247## 8.6. Определение действий по очистке248249Инструкция [`try`](https://python-all.ru/2.7/reference/compound_stmts.html#try) имеет ещё один необязательный блок, предназначенный для определения действий по очистке, которые должны быть выполнены при любых обстоятельствах. Например:250251```python252>>> try:253...     raise KeyboardInterrupt254... finally:255...     print 'Goodbye, world!'256...257Goodbye, world!258KeyboardInterrupt259Traceback (most recent call last):260  File "<stdin>", line 2, in <module>261```262263*Предложение finally* всегда выполняется перед выходом из оператора [`try`](https://python-all.ru/2.7/reference/compound_stmts.html#try), независимо от того, произошло исключение или нет. Когда исключение произошло в предложении [`try`](https://python-all.ru/2.7/reference/compound_stmts.html#try) и не было обработано предложением [`except`](https://python-all.ru/2.7/reference/compound_stmts.html#except) (или произошло в предложении [`except`](https://python-all.ru/2.7/reference/compound_stmts.html#except) или [`else`](https://python-all.ru/2.7/reference/compound_stmts.html#else)), оно возбуждается повторно после выполнения предложения [`finally`](https://python-all.ru/2.7/reference/compound_stmts.html#finally). Предложение [`finally`](https://python-all.ru/2.7/reference/compound_stmts.html#finally) также выполняется «на выходе», когда любое другое предложение оператора [`try`](https://python-all.ru/2.7/reference/compound_stmts.html#try) покидается с помощью оператора [`break`](https://python-all.ru/2.7/reference/simple_stmts.html#break), [`continue`](https://python-all.ru/2.7/reference/simple_stmts.html#continue) или [`return`](https://python-all.ru/2.7/reference/simple_stmts.html#return). Более сложный пример (наличие предложений [`except`](https://python-all.ru/2.7/reference/compound_stmts.html#except) и [`finally`](https://python-all.ru/2.7/reference/compound_stmts.html#finally) в одном операторе [`try`](https://python-all.ru/2.7/reference/compound_stmts.html#try) работает начиная с Python 2.5):264265```python266>>> def divide(x, y):267...     try:268...         result = x / y269...     except ZeroDivisionError:270...         print "division by zero!"271...     else:272...         print "result is", result273...     finally:274...         print "executing finally clause"275...276>>> divide(2, 1)277result is 2278executing finally clause279>>> divide(2, 0)280division by zero!281executing finally clause282>>> divide("2", "1")283executing finally clause284Traceback (most recent call last):285  File "<stdin>", line 1, in <module>286  File "<stdin>", line 3, in divide287TypeError: unsupported operand type(s) for /: 'str' and 'str'288```289290Как видите, блок [`finally`](https://python-all.ru/2.7/reference/compound_stmts.html#finally) выполняется в любом случае. Исключение [`TypeError`](https://python-all.ru/2.7/library/exceptions.html#exceptions.TypeError), возбуждённое при делении двух строк, не обрабатывается блоком [`except`](https://python-all.ru/2.7/reference/compound_stmts.html#except) и поэтому повторно возбуждается после выполнения блока [`finally`](https://python-all.ru/2.7/reference/compound_stmts.html#finally).291292В реальных приложениях блок [`finally`](https://python-all.ru/2.7/reference/compound_stmts.html#finally) полезен для освобождения внешних ресурсов (таких как файлы или сетевые соединения) независимо от того, было ли использование ресурса успешным.293294## 8.7. Предопределённые действия по очистке295296Некоторые объекты определяют стандартные действия по очистке, которые должны быть выполнены, когда объект больше не нужен, независимо от успеха или неудачи операции с этим объектом. Рассмотрим следующий пример, в котором предпринимается попытка открыть файл и вывести его содержимое на экран.297298```python299for line in open("myfile.txt"):300    print line,301```302303Проблема этого кода в том, что он оставляет файл открытым на неопределённое время после завершения выполнения. В простых скриптах это не является проблемой, но в больших приложениях может стать таковой. Оператор [`with`](https://python-all.ru/2.7/reference/compound_stmts.html#with) позволяет использовать такие объекты, как файлы, таким образом, что гарантируется их своевременная и корректная очистка.304305```python306with open("myfile.txt") as f:307    for line in f:308        print line,309```310311После выполнения оператора файл *f* всегда закрывается, даже если при обработке строк возникла проблема. Другие объекты, предоставляющие предопределённые действия по очистке, указывают это в своей документации.312