Введение
Как и в любом другом языке, в Python есть исключения и ошибки. В Python все исключенияBaseException
экземпляр класса. Сегодня мы подробно рассмотрим исключения в Python и способы их обработки.
Встроенные классы исключений в Python
Все классы исключений в Python происходят изBaseException, который является базовым классом для всех встроенных исключений.
Хотя это базовый класс для всех классов исключений, для определяемых пользователем классов рекомендуется наследовать не напрямую BaseException, а Exception.
Давайте сначала посмотрим на структурную связь классов исключений в Python:
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
+-- ResourceWarning
вBaseException,Exception,ArithmeticError,BufferError,LookupErrorВ основном используется как базовый класс для других исключений.
Грамматические ошибки
В Python исключения и ошибки обычно можно разделить на две категории: первая категория — это синтаксические ошибки, также известные как ошибки синтаксического анализа. То есть ошибка возникает до того, как код начал выполняться.
Причина этого в том, что написанный код не соответствует спецификации языка Python:
>>> while True print('Hello world')
File "<stdin>", line 1
while True print('Hello world')
^
SyntaxError: invalid syntax
Причина приведенного выше кода заключается в том, что перед печатью отсутствует двоеточие.
аномальный
Даже если наша программа соответствует спецификации синтаксиса python, она все равно может отправлять ошибки во время выполнения.Такие ошибки, отправленные во время выполнения, называются исключениями.
Взгляните на исключение ниже:
>>> 10 * (1/0)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ZeroDivisionError: division by zero
>>> 4 + spam*3
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'spam' is not defined
>>> '2' + 2
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: Can't convert 'int' object to str implicitly
Обработка исключений
Что делать, если в программе возникает исключение?
Мы можем использовать оператор try exclude для перехвата определенных исключений.
>>> while True:
... try:
... x = int(input("Please enter a number: "))
... break
... except ValueError:
... print("Oops! That was no valid number. Try again...")
...
Поток выполнения приведенного выше кода таков, что вложенные операторы в попытке выполняются первыми.Если не возникает исключения, исключение пропускается, и выполнение оператора попытки завершается.
Если в подоператоре в попытке возникает исключение, последняя часть предложения try будет пропущена, и будет выполнено сопоставление исключений для исключения. Если совпадение успешно, выполняется подоператор в исключении.
Если возникает исключение, которое не соответствует исключению, указанному в предложении exclude, оно передается внешнемуtry
в предложении.
У попытки может быть несколько исключений, мы можем написать это так:
try:
raise cls()
except D:
print("D")
except C:
print("C")
except B:
print("B")
У исключения также может быть несколько исключений:
... except (RuntimeError, TypeError, NameError):
... pass
Предложение exclude также может опустить имя исключения, чтобы оно соответствовало всем исключениям:
import sys
try:
f = open('myfile.txt')
s = f.readline()
i = int(s.strip())
except OSError as err:
print("OS error: {0}".format(err))
except ValueError:
print("Could not convert data to an integer.")
except:
print("Unexpected error:", sys.exc_info()[0])
raise
try
... except
оператор имеет необязательныйеще пункт, который должен быть помещен после всех, кроме предложений, когда они используются. Полезно для кода, который должен выполняться, когда предложение try не вызывает исключение. Например:
for arg in sys.argv[1:]:
try:
f = open(arg, 'r')
except OSError:
print('cannot open', arg)
else:
print(arg, 'has', len(f.readlines()), 'lines')
f.close()
кроме может указать имя переменной исключенияinstance
, эта переменная представляет этот экземпляр исключения.
Мы можем вывести аномальные параметры через instance.args.
В то же время, поскольку экземпляр исключения определяет__str__()
, так что вы можете использовать print напрямую для вывода аномальных параметров. без использования.args
.
Давайте посмотрим на пример:
>>> try:
... raise Exception('spam', 'eggs')
... except Exception as inst:
... print(type(inst)) # the exception instance
... print(inst.args) # arguments stored in .args
... print(inst) # __str__ allows args to be printed directly,
... # but may be overridden in exception subclasses
... x, y = inst.args # unpack args
... print('x =', x)
... print('y =', y)
...
<class 'Exception'>
('spam', 'eggs')
('spam', 'eggs')
x = spam
y = eggs
В приведенном выше примере мы создали исключение в предложении try и указали 2 параметра.
Выбросить исключение
Мы можем использовать оператор повышения для создания исключений.
>>> raise NameError('HiThere')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: HiThere
Аргументом для возбуждения является исключение, которое может быть экземпляром исключения или классом исключения.
Обратите внимание, что этот класс исключений должен быть
Exception
подкласс .
Если передается класс исключения, будет вызван конструктор без аргументов для неявного создания экземпляра:
raise ValueError # shorthand for 'raise ValueError()'
Если мы поймаем какое-то исключение, но не хотим его обрабатывать, мы можем использовать повышение в операторе исключения, чтобы повторно сгенерировать исключение.
>>> try:
... raise NameError('HiThere')
... except NameError:
... print('An exception flew by!')
... raise
...
An exception flew by!
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
NameError: HiThere
цепочка исключений
Если мы поймаем исключение A с помощью исключения, мы можем снова сгенерировать исключение другого типа B с помощью оператора повышения.
Тогда аномальная информация, которую мы видим, является информацией Б. Но мы не знаем, откуда взялось исключение B. На данный момент мы можем использовать цепочку исключений.
Цепочка исключений — это когда возникает исключение, используйте оператор повышения из:
>>> def func():
... raise IOError
...
>>> try:
... func()
... except IOError as exc:
... raise RuntimeError('Failed to open database') from exc
...
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
File "<stdin>", line 2, in func
OSError
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "<stdin>", line 4, in <module>
RuntimeError: Failed to open database
В приведенном выше примере после перехвата IOError мы снова выбрасываем RuntimeError.Используя цепочку исключений, мы можем четко увидеть связь между этими двумя исключениями.
По умолчанию, если исключение выдается из exclude или finally, оно автоматически выводит информацию о цепочке исключений.
Если вы не хотите создавать цепочку исключений, вы можетеfrom None
.
try:
open('database.sqlite')
except IOError:
raise RuntimeError from None
Traceback (most recent call last):
File "<stdin>", line 4, in <module>
RuntimeError
Пользовательское исключение
Пользователи могут наследовать Exception для реализации пользовательских исключений. Давайте рассмотрим несколько примеров пользовательских исключений:
class Error(Exception):
"""Base class for exceptions in this module."""
pass
class InputError(Error):
"""Exception raised for errors in the input.
Attributes:
expression -- input expression in which the error occurred
message -- explanation of the error
"""
def __init__(self, expression, message):
self.expression = expression
self.message = message
class TransitionError(Error):
"""Raised when an operation attempts a state transition that's not
allowed.
Attributes:
previous -- state at beginning of transition
next -- attempted new state
message -- explanation of why the specific transition is not allowed
"""
def __init__(self, previous, next, message):
self.previous = previous
self.next = next
self.message = message
finally
За оператором try может следовать оператор finally для реализации некоторых завершающих штрихов.
>>> try:
... raise KeyboardInterrupt
... finally:
... print('Goodbye, world!')
...
Goodbye, world!
KeyboardInterrupt
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
finally
пункт будетtry
Выполняется последняя задача перед окончанием оператора, и код в операторе finally будет выполняться независимо от того, возникнет ли исключение в попытке.
еслиfinally
пункт содержитreturn
заявление, возвращаемое значение будет получено изfinally
один из пунктовreturn
возвращаемое значение оператора, а не изtry
Пунктreturn
Возвращаемое значение оператора.
>>> def bool_return():
... try:
... return True
... finally:
... return False
...
>>> bool_return()
False
Эта статья была включена вwoohoo.floydpress.com/09-python-oh…
Самая популярная интерпретация, самая глубокая галантерея, самые краткие уроки и множество трюков, о которых вы не знаете, ждут вас!
Добро пожаловать, чтобы обратить внимание на мой официальный аккаунт: «Программируйте эти вещи», разбирайтесь в технологиях, лучше поймите себя!