Что такое исключения в программировании
Что такое исключения в программировании
Простая работа с исключениями

Боль­шин­ство наших про­ек­тов устро­е­ны так: когда во вре­мя рабо­ты про­грам­мы воз­ни­ка­ет какая-то ошиб­ка, то про­грам­ма ава­рий­но завер­ша­ет­ся. Ино­гда при этом она выда­ёт сооб­ще­ние об ошиб­ке. Кажет­ся, что это нор­маль­ная ситу­а­ция, но на самом деле боль­шин­ство оши­бок мож­но преду­смот­реть и научить про­грам­му пра­виль­но с ними рабо­тать. Для это­го нам нуж­ны обра­бот­чи­ки ошибок. 

Что такое обработчик ошибок

Что­бы про­грам­ма зна­ла, что делать, если воз­ник­ла какая-то ошиб­ка, исполь­зу­ют обра­бот­чи­ки исклю­чи­тель­ных ситу­а­ций, или, про­ще гово­ря, обра­бот­чи­ки исклю­че­ний. Смысл такой:

  1. Мы зара­нее при­ки­ды­ва­ем, в каком месте и поче­му может воз­ник­нуть ошибка.
  2. Пишем в этом месте спе­ци­аль­ный код, кото­рый пре­ду­пре­дит ком­пью­тер, что это пла­но­вая ошиб­ка и что у нас уже есть реше­ние, мол, всё под контролем.
  3. Ком­пью­тер при­ме­ня­ет наше реше­ние и пере­хо­дит к сле­ду­ю­щей команде.
  4. Про­грам­ма не пада­ет, не завер­ша­ет­ся с ошиб­кой, а про­дол­жа­ет работать.

Такие обра­бот­чи­ки есть не в каж­дом язы­ке про­грам­ми­ро­ва­ния, но боль­шин­ство совре­мен­ных язы­ков это уме­ют делать. 

Пример программы без обработчика исключений

Допу­стим, у нас в про­грам­ме на Python преду­смот­ре­но чте­ние дан­ных из фай­ла и есть такой код:

file = open("myfile2.txt")

Но если на дис­ке это­го фай­ла не будет, то ком­пью­тер, когда дой­дёт до этой строч­ки, выдаст ошибку:

Что такое обработчик ошибок

Давай­те нари­су­ем это в виде про­стой схемы:

Что такое обработчик ошибок

Полу­ча­ет­ся, что наша зада­ча — преду­смот­реть вари­ант, что на дис­ке не будет нуж­но­го фай­ла, и при­ду­мать пове­де­ние про­грам­мы в этом слу­чае. Исполь­зу­ем для это­го обра­бот­чик исключений.

Программа с обработчиком исключений

Если мы зна­ем, что в каком-то месте воз­мож­на ошиб­ка, то можем тогда преду­смот­реть этот сце­на­рий и под­стра­хо­вать­ся. Для это­го исполь­зу­ют обра­бот­чик и дела­ют так:

  1. В том месте, где мож­но преду­смот­реть ошиб­ку, дела­ют спе­ци­аль­ный блок.
  2. В этом бло­ке запус­ка­ют коман­ду и смот­рят, будет ошиб­ка или нет.
  3. Если ошиб­ки нет — про­грам­ма рабо­та­ет дальше.
  4. Если воз­ник­ла ошиб­ка — выпол­нят­ся то, что напи­са­но в обра­бот­чи­ке оши­бок, а потом про­грам­ма рабо­та­ет дальше.

В этой ситу­а­ции про­грам­ма не завис­нет и не выва­лит­ся с ошиб­кой, а сама смо­жет её обра­бо­тать и делать даль­ше то, что нужно:

Что такое исключения в программировании
try:
    file = open("myfile2.txt")
except FileNotFoundError:
    print("Файл не найден, создаю новый")
    file = open("myfile2.txt","a")

Коман­да try — это нача­ло наше­го обра­бот­чи­ка исклю­че­ний. Она гово­рит ком­пью­те­ру: «Попро­буй выпол­нить вот эту коман­ду, а мы посмот­рим, что произойдёт». 

Except — это какую ошиб­ку мы ожи­да­ем здесь уви­деть. В нашем слу­чае мы хотим преду­смот­реть слу­чай, что тако­го фай­ла нет, поэто­му пишем стан­дарт­ную ошиб­ку для такой ситуации. 

👉 Срав­ни­те текст этой ошиб­ки с тем, что нам выдал ком­пью­тер в преды­ду­щем разделе. 

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

Когда что-то не предусмотрено — будет ошибка

Если про­грам­ме в этом бло­ке встре­тит­ся дру­гая ошиб­ка, не та, кото­рую мы преду­смот­ре­ли, то про­грам­ма оста­но­вит­ся и всё пере­ста­нет рабо­тать. Напри­мер, вот какие ошиб­ки могут воз­ник­нуть с файлом:

  • файл есть на дис­ке, но к нему нет прав доступа;
  • файл занят дру­гой программой;
  • сам диск повре­ждён и дан­ные не читаются.

Во всех этих слу­ча­ях про­грам­ма сло­ма­ет­ся, пото­му что мы не преду­смот­ре­ли эти ситуации:

Что такое исключения в программировании

Получается, всё нужно делать с обработкой исключений?

Нет, и вот почему:

  1. Обра­бот­ка исклю­че­ний зани­ма­ет лиш­нее вре­мя, поэто­му про­грам­ма с ними рабо­та­ет мед­лен­нее, чем без них.
  2. Не всё мож­но преду­смот­реть. Если раз­ра­бот­чик не зна­ет, что здесь может быть ошиб­ка, то и преду­смот­реть он это тоже не сможет.
  3. Кон­струк­ции с обра­бот­чи­ка­ми дела­ют код менее чита­е­мым и понят­ным для чело­ве­ка. Ему нуж­но будет дер­жать в голо­ве точ­ку нача­ла обра­бот­ки, понять, как обра­бот­ка вли­я­ет на про­грам­му в целом, и выяс­нить, что будет с про­грам­мой после рабо­ты обра­бот­чи­ка ошибок.

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

Текст:

Миха­ил Полянин

Редак­ту­ра:

Мак­сим Ильяхов

Худож­ник:

Даня Бер­ков­ский

Кор­рек­тор:

Ири­на Михеева

Вёрст­ка:

Мария Дро­но­ва

Соц­се­ти:

Олег Веш­кур­цев