• en
  • Language: ru
  • Documentation version: latest

17. Исключения

Обработка исключений - это искусство, овладев которым, вы получите огромные возможности. Я собираюсь показать вам некоторые способы, с помощью которых мы можем обрабатывать исключения.

В базовой терминологии мы знаем о структуре try/except. Код, который может вызвать исключение, помещается в блок try, а обработка исключения осуществляется в блоке except. Код в блоке except будет выполняться только в том случае, если блок try столкнется с исключением. Вот простой пример:

try:
    file = open('test.txt', 'rb')
except IOError as e:
    print('An IOError occurred. {}'.format(e.args[-1]))

В приведенном выше примере мы обрабатываем только исключение IOError. Большинство новичков не знают, что мы можем обрабатывать несколько исключений.

17.1. Обработка нескольких исключений:

Мы можем использовать три метода для обработки множества исключений. Первый включает в себя помещение всех исключений, которые могут возникнуть, в кортеж. Например:

try:
    file = open('test.txt', 'rb')
except (IOError, EOFError) as e:
    print("An error occurred. {}".format(e.args[-1]))

Другой метод заключается в обработке отдельных исключений в отдельных блоках except. Мы можем иметь столько блоков except, сколько захотим. Вот пример:

try:
    file = open('test.txt', 'rb')
except EOFError as e:
    print("An EOF error occurred.")
    raise e
except IOError as e:
    print("An error occurred.")
    raise e

Таким образом, если исключение не обработано первым блоком except, то оно может быть обработано следующим блоком или вообще не обработано. Последний метод предполагает отлов ВСЕХ исключений:

try:
    file = open('test.txt', 'rb')
except Exception as e:
    # Some logging if you want
    raise e

Это может быть полезно, когда вы не имеете представления об исключениях, которые могут быть брошены вашей программой. Если вы просто хотите перехватить все исключения, но не заботитесь об их сути, вы можете даже исключить часть Exception as e.

Примечание:: перехват всех исключений может иметь непредвиденные последствия, поскольку перехват всех исключений может также перехватить те, которые вы хотите, чтобы произошли; например, во многих программах, основанных на командной строке, нажатие control+c приведет к завершению программы, но если вы перехватите все исключения, KeyboardInterrupt будет перехвачено как исключение, поэтому нажатие control+c НЕ приведет к завершению программы.

17.1.1. finally оговорка

Мы обернули наш основной код в предложение try. После этого мы обернем некоторый код в предложение except, которое будет выполнено, если в коде, обернутом в предложение try, возникнет исключение. В этом примере мы будем использовать и третий пункт, который является пунктом finally. Код, обернутый в предложение finally, будет выполняться независимо от того, произошло исключение или нет. Его можно использовать для очистки после выполнения сценария. Вот простой пример:

try:
    file = open('test.txt', 'rb')
except IOError as e:
    print('An IOError occurred. {}'.format(e.args[-1]))
finally:
    print("This would be printed whether or not an exception occurred!")

# Output: An IOError occurred. No such file or directory
# This would be printed whether or not an exception occurred!

17.1.2. try/else оговорка

Часто мы можем захотеть, чтобы некоторый код выполнялся, если нет исключения. Этого можно легко добиться, используя предложение else. Кто-то может спросить: почему, если вы хотите, чтобы некоторый код выполнялся только при отсутствии исключений, вы не поместите этот код внутрь try? Ответ заключается в том, что тогда любые исключения в этом коде будут перехвачены try, а вы можете этого не хотеть. Большинство людей не используют эту функцию, и, честно говоря, я сам не использовал ее широко. Вот пример:

try:
    print('I am sure no exception is going to occur!')
except Exception:
    print('exception')
else:
    # any code that should only run if no exception occurs in the try,
    # but for which exceptions should NOT be caught
    print('This would only run if no exception occurs. And an error here '
          'would NOT be caught.')
finally:
    print('This would be printed in every case.')

# Output: I am sure no exception is going to occur!
# This would only run if no exception occurs. And an error here would NOT be caught
# This would be printed in every case.

Пункт else будет выполняться только в том случае, если не произойдет исключения, и будет выполняться перед пунктом finally.