Остановить программу с ошибкой python

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

Общие исключения

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

  1. ZeroDivisionError: возникает при делении числа на ноль.
  2. NameError: возникает, когда имя не найдено. Может быть локальным или глобальным.
  3. IndentationError: если задан неправильный отступ.
  4. IOError: возникает при сбое операции ввода-вывода.
  5. EOFError: происходит, когда достигается конец файла, но операции выполняются.

Исключение можно определить как необычное условие в программе, приводящее к прерыванию выполнения программы.

Всякий раз, когда возникает исключение, программа останавливает выполнение, и, таким образом, дальнейший код не выполняется. Таким образом, исключением являются ошибки времени выполнения, которые невозможно обработать скриптом Python. Исключением является объект Python, представляющий ошибку.

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

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

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

Как мы уже обсуждали, исключение – это ненормальное состояние, которое останавливает выполнение программы.

Предположим, у нас есть две переменные a и b, которые принимают ввод от пользователя и выполняют деление этих значений. Что, если пользователь ввел ноль в качестве знаменателя? Это прервет выполнение программы и вызовет исключение ZeroDivision. Посмотрим на следующий пример.

 
a = int(input("Enter a:"))   
b = int(input("Enter b:"))   
c = a/b 
print("a/b = %d" %c)   
   
#other code:   
print("Hi I am other part of the program") 
Enter a:10
Enter b:0
Traceback (most recent call last):
  File "exception-test.py", line 3, in <module>
    c = a/b;
ZeroDivisionError: division by zero 

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

Если программа Python содержит подозрительный код, который может вызвать исключение, мы должны поместить этот код в блок try. За блоком try должен следовать оператор except, который содержит блок кода, который будет выполнен, если в блоке try возникнет какое-либо исключение.

Обработка исключений Python

 
try:   
    #block of code    
   
except Exception1:   
    #block of code   
   
except Exception2:   
    #block of code   
   
#other code   
 
try: 
    a = int(input("Enter a:"))   
    b = int(input("Enter b:"))   
    c = a/b 
except: 
    print("Can't divide with zero") 
Enter a:10 
Enter b:0 
Can't divide with zero 

Мы также можем использовать оператор else с оператором try-except, в который мы можем поместить код, который будет выполняться в сценарии, если в блоке try не возникает исключения.

Синтаксис для использования оператора else с оператором try-except приведен ниже.

 
try:   
    #block of code    
   
except Exception1:   
    #block of code    
   
else:   
    #this code executes if no except block is executed   

try-expect-else

Рассмотрим следующую программу.

 
try:   
    a = int(input("Enter a:"))   
    b = int(input("Enter b:"))   
    c = a/b 
    print("a/b = %d"%c)   
# Using Exception with except statement. If we print(Exception) it will return exception class 
except Exception:   
    print("can't divide by zero")   
    print(Exception) 
else:   
    print("Hi I am else block")    
Enter a:10 
Enter b:0 
can't divide by zero 
<class 'Exception'> 

Back to top

Toggle table of contents sidebar

В Python есть несколько операторов, которые позволяют менять поведение
циклов по умолчанию.

Оператор break#

Оператор позволяет досрочно прервать цикл:

  • break прерывает текущий цикл и продолжает выполнение следующих выражений

  • если используется несколько вложенных циклов, break прерывает внутренний цикл
    и продолжает выполнять выражения, следующие за блоком
    * break может использоваться в циклах for и while

Пример с циклом for:

     
           
            
        
            
   







Пример с циклом while:

    
     
           
            
        
            
              
   





Использование break в примере с запросом пароля (файл
check_password_with_while_break.py):

  'Введите имя пользователя: '
  'Введите пароль: '

 
       
        'Пароль слишком короткий
       
        'Пароль содержит имя пользователя
    
        'Пароль для пользователя 
        # завершает цикл while
        
      'Введите пароль еще раз: '

Теперь можно не повторять строку
в каждом ответвлении,
достаточно перенести ее в конец цикла.

И, как только будет введен правильный пароль, break выведет программу из
цикла while.

Оператор continue#

Оператор continue возвращает управление в начало цикла. То есть,
continue позволяет «перепрыгнуть» оставшиеся выражения в цикле и перейти
к следующей итерации.

Пример с циклом for:

     
           
            
        
            
   




Пример с циклом while:

    
     
          
           
            
            
            "Это никто не увидит"
        
            "Текущее значение: " 
   
   
   
 
   
   
   

Использование continue в примере с запросом пароля (файл
check_password_with_while_continue.py):

  'Введите имя пользователя: '
  'Введите пароль: '

  

  
       
        'Пароль слишком короткий
       
        'Пароль содержит имя пользователя
    
        'Пароль для пользователя 
          
        
      'Введите пароль еще раз: '

Тут выход из цикла выполнятся с помощью проверки флага
password_correct. Когда был введен правильный пароль, флаг выставляется
равным True, и с помощью continue выполняется переход в начало цикла,
перескочив последнюю строку с запросом пароля.

Результат выполнения будет таким:

$ python check_password_with_while_continue.py
Введите имя пользователя: nata
Введите пароль: nata12
Пароль слишком короткий

Введите пароль еще раз: natalksdjflsdjf
Пароль содержит имя пользователя

Введите пароль еще раз: asdfsujljhdflaskjdfh
Пароль для пользователя nata установлен

Оператор pass#

Оператор ничего не делает. Фактически, это такая заглушка для
объектов.

Например, может помочь в ситуации, когда нужно прописать
структуру скрипта. Его можно ставить в циклах, функциях, классах. И это
не будет влиять на исполнение кода.

Пример использования pass:

     
           
            
        
            
   


Из данной статьи вы узнаете, как обрабатывать исключения в программах, написанных на языке Python, при помощи инструкций try, except и finally. Также все это будет проиллюстрированно многочисленными примерами.

В языке Python существует множество встроенных исключений, которые вызываются, когда программа сталкивается с ошибкой (что-то в программе идет не так).

Когда такое исключение возникает, интерпретатор Python останавливает текущий процесс и передает управление новому, для обработки данного исключения. Если его не удается обработать, программа аварийно завершается.

Например, пусть в нашей программе есть функция А, которая вызывает функцию В, которая в свою очередь вызывает функцию С. Если исключение возникнет в функции C, но не будет в этой функции обработано, то оно будет передано в функцию B и далее в функцию А.

Если это исключение нигде не будет обработано, то программа прекратит свое исполнение и выдаст ошибку.

Перехват исключений в Python

В Python исключения обрабатываются при помощи инструкции try.

Критическая операция, которая может вызвать исключение, помещается внутрь блока try. А код, при помощи которого это исключение будет обработано, — внутрь блока except.

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

# Для получения типа исключения импортируем модуль sys
import sys

randomList = ['a', 0, 2]

for entry in randomList:
    try:
        print("The entry is", entry)
        r = 1/int(entry)
        break
    except:
        print("Oops!", sys.exc_info()[0], "occurred.")
        print("Next entry.")
        print()
print("The reciprocal of", entry, "is", r)

Результат:

The entry is a
Oops! <class 'ValueError'> occurred.
Next entry.

The entry is 0
Oops! <class 'ZeroDivisionError'> occured.
Next entry.

The entry is 2
The reciprocal of 2 is 0.5

В данном примере мы, при помощи цикла for, производим итерацию списка randomList. Как мы ранее заметили, часть кода, в которой может произойти ошибка, помещена внутри блока try.

Если исключений не возникает, блок except пропускается, а программа продолжает выполнятся обычным образом (в данном примере так происходит с последним элементом списка). Но если исключение появляется, оно сразу обрабатывается в блоке except (в данном примере так происходит с первым и вторым элементом списка).

В нашем примере мы вывели на экран имя исключения при помощи функции exc_info(), которую импортировали из модуля sys. Можно заметить, что элемент a вызывает ValueError, а 0 вызывает ZeroDivisionError.

Так как все исключения в Python наследуются из базового класса Exception, мы можем переписать наш код следующим образом:

# Для получения типа исключения импортируем модуль sys
import sys

randomList = ['a', 0, 2]

for entry in randomList:
    try:
        print("The entry is", entry)
        r = 1/int(entry)
        break
    except Exception as e:
        print("Oops!", e.__class__, "occurred.")
        print("Next entry.")
        print()
print("The reciprocal of", entry, "is", r)

Результат выполнения этого кода будет точно таким же.

Перехват определенных исключений в Python

В предыдущем примере мы не специфицировали перехватываемые исключения в блоке except.

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

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

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

try:
   # do something
   pass

except ValueError:
   # handle ValueError exception
   pass

except (TypeError, ZeroDivisionError):
   # handle multiple exceptions
   # TypeError and ZeroDivisionError
   pass

except:
   # handle all other exceptions
   pass

Вызов исключений в Python

В Python исключения автоматически вызываются, когда во время выполнения программы возникает ошибка. Но мы и сами можем вызвать исключение, используя для этого инструкцию raise.

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

>>> raise KeyboardInterrupt
Traceback (most recent call last):
...
KeyboardInterrupt

>>> raise MemoryError("This is an argument")
Traceback (most recent call last):
...
MemoryError: This is an argument

>>> try:
...     a = int(input("Enter a positive integer: "))
...     if a <= 0:
...         raise ValueError("That is not a positive number!")
... except ValueError as ve:
...     print(ve)
...    
Enter a positive integer: -2
That is not a positive number!

Конструкция try с блоком else

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

Замечание: исключения, возникающие в самом блоке else, не будут обработаны в предшествующем ему блоке except.

Давайте рассмотрим следующий пример:

# программа для вывода на экран обратных значений четных чисел

try:
    num = int(input("Введите число: "))
    assert num % 2 == 0
except:
    print("Число нечетное!")
else:
    reciprocal = 1/num
    print(reciprocal)

Результат:

Если мы вводим нечетное число:

Введите число: 1
Число нечетное!

А если вводим четное, то обратное ему число вычисляется и выводится на экран.

Введите число: 4
0.25

Однако, если мы введем 0, то получим в результате ошибку ZeroDivisionError, так как код в блоке else не обрабатывается в предшествующем ему блоке except.

Введите число: 0
Traceback (most recent call last):
  File "<string>", line 7, in <module>
    reciprocal = 1/num
ZeroDivisionError: division by zero

Конструкция try…finally

Инструкция try может также иметь и необязательный блок finally. Этот блок кода будет выполнен в любом случае и обычно используется для освобождения внешних ресурсов.

Читать также:  "Как обновить Windows 8.1 до OS 10"

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

Вот пример операций с файлом, который иллюстрирует это:

try:
   f = open("test.txt",encoding = 'utf-8')
   # perform file operations
finally:
   f.close()

Такая конструкция гарантирует нам, что файл будет закрыт в любом случае, какое бы исключение в работе кода не возникло.

Toggle table of contents sidebar

try/except#

Если вы повторяли примеры, которые использовались ранее, то наверняка
были ситуации, когда выскакивала ошибка. Скорее всего, это была ошибка
синтаксиса, когда не хватало, например, двоеточия.

Как правило, Python довольно понятно реагирует на подобные ошибки, и их
можно исправить.

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

  

   

    

     

В данном случае возникло два исключения: ZeroDivisionError и
TypeError.

Чаще всего можно предсказать, какого рода исключения возникнут во время
исполнения программы.

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

Python позволяет работать с исключениями. Их можно перехватывать и
выполнять определенные действия в том случае, если возникло исключение.

Когда в программе возникает исключение, она сразу завершает работу.

Для работы с исключениями используется конструкция :

  
        
     
        "You can't divide by zero"
   
 't divide by zero

Конструкция try работает таким образом:

  • сначала выполняются выражения, которые записаны в блоке try

  • если при выполнения блока try не возникло никаких исключений, блок except пропускается,
    и выполняется дальнейший код

  • если во время выполнения блока try в каком-то месте возникло исключение,
    оставшаяся часть блока try пропускается

    • если в блоке except указано исключение, которое возникло, выполняется код в блоке except

    • если исключение, которое возникло, не указано в блоке except,
      выполнение программы прерывается и выдается ошибка

Обратите внимание, что строка в блоке try не выводится:

  
        "Let's divide some numbers"
        
        
     
        "You can't divide by zero"
   
's divide some numbers
 't divide by zero

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

Например, скрипт divide.py делит два числа введенных пользователем:

# -*- coding: utf-8 -*-


      "Введите первое число: "
      "Введите второе число: "
     
 
    "Пожалуйста, вводите только числа"
 
    "На ноль делить нельзя"

Примеры выполнения скрипта:

$ python divide.py
Введите первое число: 3
Введите второе число: 1
Результат:  3

$ python divide.py
Введите первое число: 5
Введите второе число: 0
На ноль делить нельзя

$ python divide.py
Введите первое число: qewr
Введите второе число: 3
Пожалуйста, вводите только числа

В данном случае исключение ValueError возникает, когда пользователь
ввел строку вместо числа, во время перевода строки в число.

Исключение ZeroDivisionError возникает в случае, если второе число было
равным 0.

Если нет необходимости выводить различные сообщения на ошибки ValueError
и ZeroDivisionError, можно сделать так (файл divide_ver2.py):

# -*- coding: utf-8 -*-


      "Введите первое число: "
      "Введите второе число: "
     
  
    
$ python divide_ver2.py
Введите первое число: wer
Введите второе число: 4
Что-то пошло не так...

$ python divide_ver2.py
Введите первое число: 5
Введите второе число: 0
Что-то пошло не так...

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

Это делать не рекомендуется!

try/except/else#

В конструкции try/except есть опциональный блок else. Он выполняется в
том случае, если не было исключения.

Например, если необходимо выполнять в дальнейшем какие-то операции с
данными, которые ввел пользователь, можно записать их в блоке else (файл
divide_ver3.py):

# -*- coding: utf-8 -*-


      "Введите первое число: "
      "Введите второе число: "
      
  
    

    "Результат в квадрате: " 
$ python divide_ver3.py
Введите первое число: 10
Введите второе число: 2
Результат в квадрате:  25

$ python divide_ver3.py
Введите первое число: werq
Введите второе число: 3
Что-то пошло не так...

try/except/finally#

Блок finally — это еще один опциональный блок в конструкции try. Он
выполняется всегда, независимо от того, было ли исключение или нет.

Сюда ставятся действия, которые надо выполнить в любом случае. Например,
это может быть закрытие файла.

Файл divide_ver4.py с блоком finally:

# -*- coding: utf-8 -*-


      "Введите первое число: "
      "Введите второе число: "
      
  
    

    "Результат в квадрате: " 

    "Вот и сказочке конец, а кто слушал - молодец."
$ python divide_ver4.py
Введите первое число: 10
Введите второе число: 2
Результат в квадрате:  25
Вот и сказочке конец, а кто слушал - молодец.

$ python divide_ver4.py
Введите первое число: qwerewr
Введите второе число: 3
Что-то пошло не так...
Вот и сказочке конец, а кто слушал - молодец.

$ python divide_ver4.py
Введите первое число: 4
Введите второе число: 0
Что-то пошло не так...
Вот и сказочке конец, а кто слушал - молодец.

Когда использовать исключения#

Как правило, один и тот же код можно написать и с использованием
исключений, и без них.

Например, этот вариант кода:

 
      "Введите число: "
      "Введите второе число: "
    
          
     
        "Поддерживаются только числа"
     
        "На ноль делить нельзя"
    
        
        

Можно переписать таким образом без try/except (файл
try_except_divide.py):

 
      "Введите число: "
      "Введите второе число: "
       
           
            "На ноль делить нельзя"
        
            
            
    
        "Поддерживаются только числа"

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

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

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

raise#

Иногда в коде надо сгенерировать исключение, это можно сделать так:

 "При выполнении команды возникла ошибка"

Встроенные исключения#

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

Например, TypeError обычно генерируется когда ожидался один тип данных, а передали другой

    

                                     
  
    
        

ValueError когда значение не соответствует ожидаемому:

  

                                    
  
  
        

В этом руководстве мы расскажем, как обрабатывать исключения в Python с помощью try и except. Рассмотрим общий синтаксис и простые примеры, обсудим, что может пойти не так, и предложим меры по исправлению положения.

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

Для обработки большей части этих ошибок как исключений в Python есть блоки try и except.

Для начала разберем синтаксис операторов try и except в Python. Общий шаблон представлен ниже:

try:
	# В этом блоке могут быть ошибки
    
except <error type>:
	# Сделай это для обработки исключения;
	# выполняется, если блок try выбрасывает ошибку
    
else:
	# Сделай это, если блок try выполняется успешно, без ошибок
   
finally:
	# Этот блок выполняется всегда

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

Блок try

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

Блок except

Блок except запускается, когда блок try не срабатывает из-за исключения. Инструкции в этом блоке часто дают некоторый контекст того, что пошло не так внутри блока try.

Если собираетесь перехватить ошибку как исключение, в блоке except нужно обязательно указать тип этой ошибки. В приведенном выше сниппете место для указания типа ошибки обозначено плейсхолдером <error type> .

except можно использовать и без указания типа ошибки. Но лучше так не делать. При таком подходе не учитывается, что возникающие ошибки могут быть разных типов. То есть вы будете знать, что что-то пошло не так, но что именно произошло, какая была ошибка — вам будет не известно.

При попытке выполнить код внутри блока try также существует вероятность возникновения нескольких ошибок.

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

В результате вы можете столкнуться с IndexError, KeyError и FileNotFoundError. В таком случае нужно добавить столько блоков except, сколько ошибок ожидается – по одному для каждого типа ошибки.

Блок else

Блок else запускается только в том случае, если блок try выполняется без ошибок. Это может быть полезно, когда нужно выполнить ещё какие-то действия после успешного выполнения блока try. Например, после успешного открытия файла вы можете прочитать его содержимое.

Блок finally

Блок finally выполняется всегда, независимо от того, что происходит в других блоках. Это полезно, когда вы хотите освободить ресурсы после выполнения определенного блока кода.

Примечание: блоки else и finally не являются обязательными. В большинстве случаев вы можете использовать только блок try, чтобы что-то сделать, и перехватывать ошибки как исключения внутри блока except.

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

Читать также:  Программа исправитель ошибок в тексте

Обработка ZeroDivisionError

Рассмотрим функцию divide(), показанную ниже. Она принимает два аргумента – num и div – и возвращает частное от операции деления num/div.

def divide(num,div):
    return num/div

Вызов функции с разными аргументами возвращает ожидаемый результат:

res = divide(100,8)
print(res)

# Output
# 12.5

res = divide(568,64)
print(res)

# Output
# 8.875

Этот код работает нормально, пока вы не попробуете разделить число на ноль:

divide(27,0)

Вы видите, что программа выдает ошибку ZeroDivisionError:

# Output
---------------------------------------------------------------------------
ZeroDivisionError                         Traceback (most recent call last)
<ipython-input-19-932ea024ce43> in <module>()
----> 1 divide(27,0)

<ipython-input-1-c98670fd7a12> in divide(num, div)
      1 def divide(num,div):
----> 2   return num/div

ZeroDivisionError: division by zero

Можно обработать деление на ноль как исключение, выполнив следующие действия:

  1. В блоке try поместите вызов функции divide(). По сути, вы пытаетесь разделить num на div (try в переводе с английского — «пытаться», — прим. перев.).
  2. В блоке except обработайте случай, когда div равен 0, как исключение.
  3. В результате этих действий при делении на ноль больше не будет выбрасываться ZeroDivisionError. Вместо этого будет выводиться сообщение, информирующее пользователя, что он попытался делить на ноль.

Вот как все это выглядит в коде:

try:
    res = divide(num,div)
    print(res)
except ZeroDivisionError:
    print("You tried to divide by zero :( ")

При корректных входных данных наш код по-прежнему работает великолепно:

divide(10,2)
# Output
# 5.0

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

divide(10,0)
# Output
# You tried to divide by zero :(

Обработка TypeError

В этом разделе мы разберем, как использовать try и except для обработки TypeError в Python.

Рассмотрим функцию add_10(). Она принимает число в качестве аргумента, прибавляет к нему 10 и возвращает результат этого сложения.

def add_10(num):
    return num + 10

Вы можете вызвать функцию add_10() с любым числом, и она будет работать нормально, как показано ниже:

result = add_10(89)
print(result)

# Output
# 99

Теперь попробуйте вызвать функцию add_10(), передав ей в качестве аргумента не число, а строку.

add_10 ("five")

Ваша программа вылетит со следующим сообщением об ошибке:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-15-9844e949c84e> in <module>()
----> 1 add_10("five")

<ipython-input-13-2e506d74d919> in add_10(num)
      1 def add_10(num):
----> 2   return num + 10

TypeError: can only concatenate str (not "int") to str

Сообщение об ошибке TypeError: can only concatenate str (not "int") to str говорит о том, что можно сложить только две строки, а не добавить целое число к строке.

  • В блок try мы помещаем вызов функции add_10() с my_num в качестве аргумента. Если аргумент допустимого типа, исключений не возникнет.
  • В противном случае срабатывает блок except, в который мы помещаем вывод уведомления для пользователя о том, что аргумент имеет недопустимый тип.

Это показано ниже:

my_num = "five"
try:
    result = add_10(my_num)
    print(result)
except TypeError:
    print("The argument `num` should be a number")

Поскольку теперь вы обработали TypeError как исключение, при передаче невалидного аргумента ошибка не возникает. Вместо нее выводится сообщение, что аргумент имеет недопустимый тип.

The argument `num` should be a number

Обработка IndexError

Если вам приходилось работать со списками или любыми другими итерируемыми объектами, вы, вероятно, сталкивались с IndexError.

Это связано с тем, что часто бывает сложно отслеживать все изменения в итерациях. И вы можете попытаться получить доступ к элементу по невалидному индексу.

В этом примере список my_list состоит из 4 элементов. Допустимые индексы — 0, 1, 2 и 3 и -1, -2, -3, -4, если вы используете отрицательную индексацию.

Поскольку 2 является допустимым индексом, вы видите, что элемент с этим индексом (C++) распечатывается:

my_list = ["Python","C","C++","JavaScript"]
print(my_list[2])

# Output
# C++

Но если вы попытаетесь получить доступ к элементу по индексу, выходящему за пределы допустимого диапазона, вы столкнетесь с IndexError:

print(my_list[4])
---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
<ipython-input-7-437bc6501dea> in <module>()
      1 my_list = ["Python","C","C++","JavaScript"]
----> 2 print(my_list[4])

IndexError: list index out of range

Теперь вы уже знакомы с шаблоном, и вам не составит труда использовать try и except для обработки данной ошибки.

В приведенном ниже фрагменте кода мы пытаемся получить доступ к элементу по индексу search_idx.

search_idx = 3
try:
    print(my_list[search_idx])
except IndexError:
    print("Sorry, the list index is out of range")

Здесь search_idx = 3 является допустимым индексом, поэтому в результате выводится соответствующий элемент — JavaScript.

Если search_idx находится за пределами допустимого диапазона индексов, блок except перехватывает IndexError как исключение, и больше нет длинных сообщений об ошибках.

search_idx = 4
try:
    print(my_list[search_idx])
except IndexError:
    print("Sorry, the list index is out of range")

Вместо этого отображается сообщение о том, что search_idx находится вне допустимого диапазона индексов:

Sorry, the list index is out of range

Обработка KeyError

Вероятно, вы уже сталкивались с KeyError при работе со словарями в Python.

Рассмотрим следующий пример, где у нас есть словарь my_dict.

my_dict ={"key1":"value1","key2":"value2","key3":"value3"}
search_key = "non-existent key"
print(my_dict[search_key])

В словаре my_dict есть 3 пары «ключ-значение»: key1:value1, key2:value2 и key3:value3.

Теперь попытаемся получить доступ к значению, соответствующему несуществующему ключу non-existent key.

Как и ожидалось, мы получим KeyError:

---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-2-2a61d404be04> in <module>()
      1 my_dict ={"key1":"value1","key2":"value2","key3":"value3"}
      2 search_key = "non-existent key"
----> 3 my_dict[search_key]

KeyError: 'non-existent key'

Вы можете обработать KeyError почти так же, как и IndexError.

  • Пробуем получить доступ к значению, которое соответствует ключу, определенному search_key.
  • Если search_key — валидный ключ, мы распечатываем соответствующее значение.
  • Если ключ невалиден и возникает исключение — задействуется блок except, чтобы сообщить об этом пользователю.

Все это можно видеть в следующем коде:

try:
    print(my_dict[search_key])
except KeyError:
    print("Sorry, that's not a valid key!")

# Output:
# Sorry, that's not a valid key!

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

Вы можете сделать это, перехватив невалидный ключ как <error_msg> и используя его в сообщении, которое печатается при возникновении исключения:

try:
    print(my_dict[search_key])
except KeyError as error_msg:
    print(f"Sorry,{error_msg} is not a valid key!")

Обратите внимание, что теперь в сообщении об ошибки указано также и имя несуществующего ключа:

Sorry, 'non-existent key' is not a valid key!

Обработка FileNotFoundError

При работе с файлами в Python часто возникает ошибка FileNotFoundError.

В следующем примере мы попытаемся открыть файл my_file.txt, указав его путь в функции open(). Мы хотим прочитать файл и вывести его содержимое.

Однако мы еще не создали этот файл в указанном месте.

my_file = open("/content/sample_data/my_file.txt")
contents = my_file.read()
print(contents)

Поэтому, попытавшись запустить приведенный выше фрагмент кода, мы получим FileNotFoundError:

---------------------------------------------------------------------------
FileNotFoundError                         Traceback (most recent call last)
<ipython-input-4-4873cac1b11a> in <module>()
----> 1 my_file = open("my_file.txt")

FileNotFoundError: [Errno 2] No such file or directory: 'my_file.txt'

А с помощью try и except мы можем сделать следующее:

  • Попробуем открыть файл в блоке try.
  • Обработаем FileNotFoundError в блоке except, сообщив пользователю, что он попытался открыть несуществующий файл.
  • Если блок try завершается успешно и файл действительно существует, прочтем и распечатаем содержимое.
  • В блоке finally закроем файл, чтобы не терять ресурсы. Файл будет закрыт независимо от того, что происходило на этапах открытия и чтения.
try:
    my_file = open("/content/sample_data/my_file.txt")
except FileNotFoundError:
    print(f"Sorry, the file does not exist")
else:
    contents = my_file.read()
    print(contents)
finally:
    my_file.close()

Обратите внимание: мы обработали ошибку как исключение, и программа завершает работу, отображая следующее сообщение:

Sorry, the file does not exist

Теперь рассмотрим случай, когда срабатывает блок else. Файл my_file.txt теперь присутствует по указанному ранее пути.

Остановить программу с ошибкой python

Вот содержимое этого файла:

Остановить программу с ошибкой python

Теперь повторный запуск нашего кода работает должным образом.

На этот раз файл my_file.txt присутствует, поэтому запускается блок else и содержимое распечатывается, как показано ниже:

Остановить программу с ошибкой python

Надеемся, теперь вы поняли, как обрабатывать исключения при работе с файлами.

Заключение

В этом руководстве мы рассмотрели, как обрабатывать исключения в Python с помощью try и except.

Также мы разобрали на примерах, какие типы исключений могут возникать и как при помощи except ловить наиболее распространенные ошибки.

Надеемся, вам понравился этот урок. Успехов в написании кода!

Перевод статьи «Python Try and Except Statements – How to Handle Exceptions in Python».

Пользовательские исключения (User-defined Exceptions) в Python

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

Для реализации собственного типа исключения необходимо создать класс, являющийся наследником от одного из классов исключений.

 ():
   

:
   val  (("input positive number: "))
    val  :
        NegValException("Neg val: "  (val))
   (val  )
 NegValException  e:
  (e)

Обработка исключений в Python

()
:
   val  (("input number: "))
   tmp    val
   (tmp)
   e:
   (  (e))
()

В приведенной выше программе возможных два вида исключений – это ValueError, возникающее в случае, если на запрос программы “введите число”, вы введете строку, и ZeroDivisionError – если вы введете в качестве числа 0.

Вывод программы при вводе нулевого числа будет таким.

start input number: 0 Error! stop

()
val  ((“ number: “))
tmp    val
(tmp)
()

Если ввести 0 на запрос приведенной выше программы, произойдет ее остановка с распечаткой сообщения об исключении.


input number: 0


Traceback (most recent call last):


 File “F:/work/programming/python/devpractice/tmp.py”, line 3, in <module>


   tmp = 10 / val


ZeroDivisionError: division by zero

Обратите внимание, надпись stop уже не печатается в конце вывода программы.

Согласно документу по языку Python, описывающему ошибки и исключения, оператор try работает следующим образом:

  • Вначале выполняется код, находящийся между операторами try и except.
  • Если в ходе его выполнения исключения не произошло, то код в блоке except пропускается, а код в блоке try выполняется весь до конца.
  • Если исключение происходит, то выполнение в рамках блока try прерывается и выполняется код в блоке except. При этом для оператора except можно указать, какие исключения можно обрабатывать в нем. При возникновении исключения, ищется именно тот блок except, который может обработать данное исключение.
  • Если среди except блоков нет подходящего для обработки исключения, то оно передается наружу из блока try. В случае, если обработчик исключения так и не будет найден, то исключение будет необработанным (unhandled exception) и программа аварийно остановится.
Читать также:  Почему вирус все еще присутствует? Что такое WorldOfWarplanes.exe? Как исправить или удалить его

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

Если бы мы в нашей программе хотели обрабатывать только ValueError и ZeroDivisionError, то программа выглядела бы так.

()
:
   val  (("input number: "))
   tmp    val
   (tmp)
(, ):
   ()
()

Или так, если хотим обрабатывать ValueError, ZeroDivisionError по отдельность, и, при этом, сохранить работоспособность при возникновении исключений отличных от вышеперечисленных.

()
:
   val  (("input number: "))
   tmp    val
   (tmp)
 :
   ()
 :
   ()
:
   ()
()

Существует возможность передать подробную информацию о произошедшем исключении в код внутри блока except.

rint()
:
   val  (("input number: "))
   tmp    val
   (tmp)
   ve:
   (.format(ve))
   zde:
   (.format(zde))
   ex:
   (.format(ex))
()

Объявление множественных исключений

Python позволяет нам объявлять множественные исключения с помощью оператора except. Объявление нескольких исключений полезно в тех случаях, когда блок try вызывает несколько исключений. Синтаксис приведен ниже.

 
try:   
    #block of code    
   
except(<Exception 1>,<Exception 2>,<Exception 3>,...<Exception n>)   
    #block of code    
   
else:   
    #block of code   

Рассмотрим следующий пример.

 
try:     
    a=10/0;     
except(ArithmeticError, IOError):     
    print("Arithmetic Exception")     
else:     
    print("Successfully Done")      
Arithmetic Exception 

Исключения в языках программирования

Исключениями (exceptions) в языках программирования называют проблемы, возникающие в ходе выполнения программы, которые допускают возможность дальнейшей ее работы в рамках основного алгоритма. Типичным примером исключения является деление на ноль, невозможность считать данные из файла (устройства), отсутствие доступной памяти, доступ к закрытой области памяти и т.п. Для обработки таких ситуаций в языках программирования, как правило, предусматривается специальный механизм, который называется обработка исключений (exception handling).

Исключения разделяют на синхронные и асинхронные. Синхронные исключения могут возникнуть только в определенных местах программы. Например, если у вас есть код, который открывает файл и считывает из него данные, то исключение типа “ошибка чтения данных” может произойти только в указанном куске кода. Асинхронные исключения могут возникнуть в любой момент работы программы, они, как правило, связаны с какими-либо аппаратными проблемами, либо приходом данных. В качестве примера можно привести сигнал отключения питания.

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

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

В Python выделяют два различных вида ошибок: синтаксические ошибки и исключения.

Оператор except без исключения

Python позволяет не указывать имя исключения в операторе исключения.

 
try:   
    a = int(input("Enter a:"))   
    b = int(input("Enter b:"))   
    c = a/b;   
    print("a/b = %d"%c)   
except:   
    print("can't divide by zero")   
else:   
    print("Hi I am else block")    

Генерация исключений в Python

Для принудительной генерации исключения используется инструкция raise.

Самый простой пример работы с raise может выглядеть так.

:
    ()
   e:
   ("Exception exception "  (e))

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

.

Если вам интересна тема анализа данных, то мы рекомендуем ознакомиться с библиотекой Pandas. На нашем сайте вы можете найти вводные уроки по этой теме. Все уроки по библиотеке Pandas собраны в книге “Pandas. Работа с данными”.
Книга: Pandas. Работа с данными

<<< Python. Урок 10. Функции в Python   Python. Урок 12. Ввод-вывод данных. Работа с файлами>>>

Иерархия исключений в Python

Существует довольно большое количество встроенных типов исключений в языке Python, все они составляют определенную иерархию, которая выглядит так, как показано ниже.

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

Вызов исключений

Исключение можно вызвать принудительно, используя условие raise в Python. Это полезно в том случае, когда нам нужно вызвать исключение, чтобы остановить выполнение программы.

Например, есть программа, для выполнения которой требуется 2 ГБ памяти, и если программа пытается занять 2 ГБ памяти, мы можем вызвать исключение, чтобы остановить выполнение программы.

Синтаксис для использования оператора повышения приведен ниже.

 
raise Exception_class,<value>

Что нужно помнить:

  1. Чтобы вызвать исключение, используется оператор raise. За ним следует имя класса исключения.
  2. В качестве исключения можно указать значение, которое может быть указано в скобках.
  3. Для доступа к значению «as» используется ключевое слово. «e» используется как ссылочная переменная, в которой хранится значение исключения.
  4. Мы можем передать значение исключению, чтобы указать тип исключения.
try:    
    age = int(input("Enter the age:"))    
    if(age<18):    
        raise ValueError   
    else:    
        print("the age is valid")    
except ValueError:    
    print("The age is not valid")
Enter the age:17
The age is not valid

Пример вызова с сообщением

try:  
     num = int(input("Enter a positive integer: "))  
     if(num <= 0):  
# we can pass the message in the raise statement  
         raise ValueError("That is  a negative number!")  
except ValueError as e:  
     print(e)
Enter a positive integer: -5
That is a negative number!
try:    
    a = int(input("Enter a:"))    
    b = int(input("Enter b:"))    
    if b is 0:    
        raise ArithmeticError  
    else:    
        print("a/b = ",a/b)    
except ArithmeticError:    
    print("The value of b can't be 0")
Enter a:10
Enter b:0
The value of b can't be 0

Синтаксические ошибки в Python

Синтаксические ошибки возникают в случае если программа написана с нарушениями требований Python к синтаксису. Определяются они в процессе парсинга программы. Ниже представлен пример с ошибочным написанием функции print.

  i  ():
    prin()

Traceback (most recent call last):
  File , line ,  module
    prin()
: name    defined

Пользовательское исключение

Python позволяет нам создавать наши собственные исключения, которые могут быть вызваны из программы и пойманы с помощью except.

class ErrorInCode(Exception):      
    def __init__(self, data):      
        self.data = data      
    def __str__(self):      
        return repr(self.data)      
      
try:      
    raise ErrorInCode(2000)      
except ErrorInCode as ae:      
    print("Received error:", ae.data)
Received error: 2000

Остановить программу с ошибкой python

Остановить программу с ошибкой python

Изучаю Python вместе с вами, читаю, собираю и записываю информацию опытных программистов.

Исключения в Python

Второй вид ошибок – это исключения. Они возникают в случае если синтаксически программа корректна, но в процессе выполнения возникает ошибка (деление на ноль и т.п.). Более подробно про понятие исключения написано выше, в разделе “исключения в языках программирования”.

Пример исключения ZeroDivisionError, которое возникает при делении на 0.

 a  
 b  
 c  a  b
Traceback (most recent call last):
  File , line ,  module
    c  a  b
: division by zero

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

Что нужно помнить

  1. Python позволяет нам не указывать исключение с помощью оператора except.
  2. Мы можем объявить несколько исключений в операторе except, поскольку блок try может содержать операторы, которые генерируют исключения другого типа.
  3. Мы также можем указать блок else вместе с оператором try-except, который будет выполнен, если в блоке try не возникнет исключение.
  4. Операторы, которые не вызывают исключения, должны быть помещены в блок else.
 
try:   
    #this will throw an exception if the file doesn't exist.    
    fileptr = open("file.txt","r")   
except IOError:   
    print("File not found")   
else:   
    print("The file opened successfully")   
    fileptr.close()   
File not found 

Оператор except с использованием переменной с исключением

Мы можем использовать переменную исключения с оператором except. Он используется с помощью ключевого слова as, этот объект вернет причину исключения. Рассмотрим следующий пример:

 
try:   
    a = int(input("Enter a:"))   
    b = int(input("Enter b:"))   
    c = a/b 
    print("a/b = %d"%c)   
    # Using exception object with the except statement 
except Exception as e:   
    print("can't divide by zero")   
    print(e) 
else:   
    print("Hi I am else block")    
Enter a:10 
Enter b:0 
can't divide by zero 
division by zero 

Блок try…finally

Python предоставляет оператор finally, который используется по желанию с оператором try. Он выполняется независимо от того, какое исключение возникает и используется для освобождения внешнего ресурса. Блок finally обеспечивает гарантию выполнения.

Мы можем использовать блок finally с блоком try, в котором мы можем выполнить необходимый код до того, как оператор try вызовет исключение.

Синтаксис для использования блока finally:

 
try:   
    # block of code    
    # this may throw an exception   
finally:   
    # block of code   
    # this will always be executed    

Блок try...finally

 
try:   
    fileptr = open("file2.txt","r")     
    try:   
        fileptr.write("Hi I am good")   
    finally:   
        fileptr.close()   
        print("file closed")   
except:   
    print("Error")   
file closed 
Error 

Использование finally в обработке исключений

Для выполнения определенного программного кода при выходе из блока try/except, используйте оператор finally.

:
   val  (("input number: "))
   tmp    val
   (tmp)
:
   ()
:
  ()

Не зависимо от того, возникнет или нет во время выполнения кода в блоке try исключение, код в блоке finally все равно будет выполнен.

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

:
   f  (, )
    line  f:
       (line)
   f.close()
   e:
   (e)
:
   ("File was readed")

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *