Основы Python: исключения и ошибки в Python

Python

Введение

Как и в любом другом языке, в 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…

Самая популярная интерпретация, самая глубокая галантерея, самые краткие уроки и множество трюков, о которых вы не знаете, ждут вас!

Добро пожаловать, чтобы обратить внимание на мой официальный аккаунт: «Программируйте эти вещи», разбирайтесь в технологиях, лучше поймите себя!