Как использовать try except python 3

Python Exception Обращаясь за лучшие практики

  • Всегда старайтесь обрабатывать исключение в коде, чтобы избежать ненормального завершения программы.
  • При создании таможенного класса исключения суффикс его название с «ошибкой».
  • Если кроме положения имеют тот же код, попробуйте поймать несколько исключений в одном кроме блока.
  • Используйте, наконец, блокировать, чтобы закрыть тяжелые ресурсы и удалить тяжелые объекты.
  • Используйте остальные блоки для журнала успешного выполнения кода, отправьте уведомления и т. Д.
  • Избегайте как можно большего размера, кроме как можно больше. Если вы не знаете об исключениях, то только используйте его.
  • Создание классов исключения для конкретных модулей для конкретных сценариев.
  • Вы можете ловить исключения в за исключением блоке, а затем поднять еще одно исключение, что является более значимым.
  • Всегда поднимайте исключения со значимыми сообщениями.
  • Избегайте вложенных блоков, кроме слоев, потому что это уменьшает читаемость кода.

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

При выполнении программ могут возникать ошибки, для управления ими Python использует специальные объекты, называемые исключениями. Когда в программу включен код обработки исключения, ваша программа продолжится, а если нет, то программа остановится и выведет трассировку с отчетом об исключении. Исключения обрабатываются в блоках try-except. С блоками try-except программы будут работать даже в том случае, если что-то пошло не так.

3.1. Блоки try-except на Python

Приведем пример простой ошибки деления на ноль:

print(7/0)

Traceback (most recent call last):
  File «example.py», line 1, in <module>
    print(7/0)
ZeroDivisionError: division by zero

Если в вашей программе возможно появление ошибки, то вы можете заранее написать блок try-except для обработки данного исключения. Приведем пример обработки ошибки ZeroDivisionError с помощью блока try-except:

try:
    print(7/0)except ZeroDivisionError:
    print(«Деление на ноль запрещено»)

Команда print(7/0) помещена в блок try. Если код в блоке try выполняется успешно, то Python пропускает блок except.  Если же код в блоке try создал ошибку, то Python ищет блок except и запускает код в этом блоке. В нашем случае в блоке except выводится сообщение «Деление на ноль запрещено». При выполнение этого кода пользователь увидит понятное сообщение:

Деление на ноль запрещено

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

3.2. Блок try-except-else на Python

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

:
    first_number = («Введите первое число: «)
     first_number == ‘q’:
        
    second_number = («Введите второе число: «)
     second_number == ‘q’:
        
    try:
        a = (first_number) / (second_number)
    except ZeroDivisionError:
        print(«Деление на ноль запрещено»)
    else:
        print(«Частное двух чисел равно {a}»)

Программа запрашивает у пользователя первое число (first_number), затем второе (second_number). Если пользователь не ввел » q » для завершения работы программа продолжается. В блок try помещаем код, в котором возможно появление ошибки. В случае отсутствия ошибки деления, выполняется код else и Python выводит результат на экран. В случае ошибки ZeroDivisionError выполняется блок except и выводится сообщение о запрете деления на ноль, а программа продолжит свое выполнение. Запустив код получим такие результаты:

Введите первое число: 30
Введите второе число: 5Частное двух чисел равно 6.0
Введите первое число: 7
Введите второе число: Деление на ноль запрещено
Введите первое число:  q

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

3.3. Блок  try-except с текстовыми файлами на Python

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

filename = ‘alice_2.txt’

with open(filename, encoding=’utf-8′) as file:
    contents = file.read()

Так как такого файла не существует, Python выдает исключение:

Traceback (most recent call last):
  File «example.py», line 3, in <module>
    with open(filename, encoding=’utf-8′) as file:
FileNotFoundError: No such file or directory: ‘alice_2.txt’

FileNotFoundError — это ошибка отсутствия запрашиваемого файла. С помощью блока try-except обработаем ее:

filename = ‘alice_2.txt’

try:
    with open(filename, encoding=’utf-8′) as file:
        contents = file.read()except FileNotFoundError:
    print(«Запрашиваемый файл {filename } не найден»)

В результате при отсутствии файла мы получим:

Запрашиваемый файл alice_2.txt не найден

3.4. Ошибки без уведомления пользователя

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

ilename = ‘alice_2.txt’

try:
    with open(filename, encoding=’utf-8′) as file:
        contents = file.read()except FileNotFoundError:
    pass

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

try…except Python: Finally

But what if we want a message to print both if an error is returned and if no error is found? That’s where the finally block comes in. If you define a finally clause, its contents will be executed irrespective of whether the try…except block raises an error.

Finally blocks are a useful indicator that you code has executed. Because they do not differentiate between whether a code has successfully executed, they are not as commonly used.

Here’s an example:

try:
	print(ourVariable)
except:
	print('ourVariable is not defined')
finally:
	print('Code has been run.')

Our program returns the following:

ourVariable is not defined
Code has been run.

The code within the except block executes because there is an exception found in our code (ourVariable is not defined). The code within the finally clause executes as well, because our code has finished running.

Не ловите “Исключение как e”

Перехват всех исключений и выбрасывание их-второй наиболее эффективный способ получить код без ошибок ( первый – удалить весь код ). Так что, конечно, это означает, что это хорошо, не так ли?

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

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

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

Разве вы не хотите, чтобы в документах Python3 были красивые диаграммы?

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

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

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

Вы будете ловить не только все эти дикие и замечательные встроенные исключения, но и все пользовательские исключения (да … за исключением тех, которые являются производными от , а не ).

Это действительно то, что ты хотел сделать? Возможно, решение состоит в том, чтобы поймать несколько конкретных пользовательских исключений (которые вы делаете с помощью кортежей), например:

catch (FileNotFoundError, IsADirectoryError, PermissionError) as e:

Это безопасно поймает , но не поймает более опасную , такую как .

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

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

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

Эмпирическое правило: поймайте как можно больше ошибок. Не ловите исключение как e, если вы точно не знаете, что делаете.

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

Exceptions

Even though when your code has valid syntax, it may cause an error during execution.

In Python, errors that occur during the execution are called exceptions. The causes of exceptions mainly come from the environment where the code executes. For example:

  • Reading a file that doesn’t exist.
  • Connecting to a remote server that is offline.
  • Bad user inputs.

When an exception occurs, the program doesn’t handle it automatically. This results in an error message.

For example, the following program calculates the sales growth:

How it works.

  • First, prompt users for entering two numbers: the net sales of the prior and current periods.
  • Then, calculate the sales growth in percentage.
  • Finally, show the result.

When you run the program and enter as the net sales of the current period, the Python interpreter will issue the following output:

The Python interpreter showed a traceback that includes detailed information of the exception:

  • The path to the source code file () that caused the exception.
  • The exact line of code that caused the exception ()
  • The statement that caused the exception
  • The type of exception
  • The error message:

Because couldn’t convert the string to a number, the Python interpreter issued a exception.

In Python, exceptions have differen types such as , , etc.

Conclusion

try…except blocks make it easy to debug your Python code. A program tries to run the code in a “try” block. If this fails, the “except” block runs. The code in a “finally” statement runs irrespective of whether an “except” block is executed.

In this tutorial, we have broken down how to use try…except blocks. We have discussed how to use else and except to customize your exception handling.

These blocks can be useful when you’re testing existing code or writing new code. It ensures that your program runs correctly and contains no errors.

For more Python learning resources, check out our comprehensive How to Learn Python guide.

Используйте Встроенные Исключения, Когда Это Разумно

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

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

Класс электромобилей python с двумя логическими переменными по умолчанию, вызывающими ошибку ValueError

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

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

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

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

Тот же пример, что и выше, но с определенным пользовательским исключением

Нужно … написать … больше … исключений.

Эмпирическое правило: всегда наследовайте от как можно более конкретного встроенного исключения. Если у вас нет дополнительной информации для добавления, просто используйте встроенное исключение.

Полный список встроенных исключений Python и их иерархию см. в официальных документах .

«Голое» исключение

Есть еще один способ поймать ошибку:

Python

try:
1 / 0
except:
print(«You cannot divide by zero!»)

1
2
3
4

try

1

except

print(«You cannot divide by zero!»)

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

Python

my_dict = {«a»:1, «b»:2, «c»:3}

try:
value = my_dict
except KeyError:
print(«That key does not exist!»)

1
2
3
4
5
6

my_dict={«a»1,»b»2,»c»3}

try

value=my_dict»d»

exceptKeyError

print(«That key does not exist!»)

Python

my_list =

try:
my_list
except IndexError:
print(«That index is not in the list!»)

1
2
3
4
5
6

my_list=1,2,3,4,5

try

my_list6

exceptIndexError

print(«That index is not in the list!»)

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

Помните, что списки в Пайтоне начинаются с нуля, так что когда вы говорите 6, вы запрашиваете 7. В любом случае, в нашем списке только пять объектов, по этой причине возникает IndexError, которую мы выявили. Вы также можете выявить несколько ошибок за раз при помощи одного оператора. Для этого существует несколько различных способов. Давайте посмотрим:

Python

my_dict = {«a»:1, «b»:2, «c»:3}

try:
value = my_dict
except IndexError:
print(«This index does not exist!»)
except KeyError:
print(«This key is not in the dictionary!»)
except:
print(«Some other error occurred!»)

1
2
3
4
5
6
7
8
9
10

my_dict={«a»1,»b»2,»c»3}

try

value=my_dict»d»

exceptIndexError

print(«This index does not exist!»)

exceptKeyError

print(«This key is not in the dictionary!»)

except

print(«Some other error occurred!»)

Это самый стандартный способ выявить несколько исключений. Сначала мы попробовали открыть доступ к несуществующему ключу, которого нет в нашем словаре. При помощи try/except мы проверили код на наличие ошибки KeyError, которая находится во втором операторе except

Обратите внимание на то, что в конце кода у нас появилась «голое» исключение. Обычно, это не рекомендуется, но вы, возможно, будете сталкиваться с этим время от времени, так что лучше быть проинформированным об этом

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

Python

try:
value = my_dict
except (IndexError, KeyError):
print(«An IndexError or KeyError occurred!»)

1
2
3
4

try

value=my_dict»d»

except(IndexError,KeyError)

print(«An IndexError or KeyError occurred!»)

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

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

В зависимости от сложности данной ошибки, вам может понадобиться выйти из программы. Иногда вам может понадобиться выполнить очистку, перед выходом из программы. Например, если вы открыли соединение с базой данных, вам нужно будет закрыть его, перед выходом из программы, или вы можете закончить с открытым соединением. Другой пример – закрытие дескриптора файла, к которому вы обращаетесь. Теперь нам нужно научиться убирать за собой. Это очень просто, если использовать оператор finally.

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

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

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

In 1]: "a" + 3
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-1-5aa8a24e3e06> in <module>
----> 1 "a" + 3
TypeError can only concatenate str (not "int") to str

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

In 2]: int("a")
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-2-d9136db7b558> in <module>
----> 1 int("a")
ValueError invalid literal for int() with base 10 'a'

Catching specific exceptions

When you enter the net sales of the prior period as zero, you’ll get the following message:

In this case, both net sales of the prior and current periods are numbers, the program still issues an error message. Another exception must occur.

The statement allows you to handle a particular exception. To catch a selected exception, you place the type of exception after the keyword:

For example:

When you run a program and enter a string for the net sales, you’ll get the same error message.

However, if you enter zero for the net sales of the prior period:

… you’ll get the following error message:

This time you got the exception. This division by zero exception caused by the following statement:

And the reason is that the value of the is zero.

8.3. Handling Exceptions¶

It is possible to write programs that handle selected exceptions. Look at the
following example, which asks the user for input until a valid integer has been
entered, but allows the user to interrupt the program (using Control-C or
whatever the operating system supports); note that a user-generated interruption
is signalled by raising the exception.

>>> while True
...     try
...         x = int(input("Please enter a number: "))
...         break
...     except ValueError
...         print("Oops!  That was no valid number.  Try again...")
...

The statement works as follows.

  • First, the try clause (the statement(s) between the and
    keywords) is executed.

  • If no exception occurs, the except clause is skipped and execution of the
    statement is finished.

  • If an exception occurs during execution of the try clause, the rest of the
    clause is skipped. Then if its type matches the exception named after the
    keyword, the except clause is executed, and then execution
    continues after the statement.

  • If an exception occurs which does not match the exception named in the except
    clause, it is passed on to outer statements; if no handler is
    found, it is an unhandled exception and execution stops with a message as
    shown above.

A statement may have more than one except clause, to specify
handlers for different exceptions. At most one handler will be executed.
Handlers only handle exceptions that occur in the corresponding try clause, not
in other handlers of the same statement. An except clause may
name multiple exceptions as a parenthesized tuple, for example:

... except (RuntimeError, TypeError, NameError):
...     pass

A class in an clause is compatible with an exception if it is
the same class or a base class thereof (but not the other way around — an
except clause listing a derived class is not compatible with a base class). For
example, the following code will print B, C, D in that order:

class B(Exception):
    pass

class C(B):
    pass

class D(C):
    pass

for cls in B, C, D]:
    try
        raise cls()
    except D
        print("D")
    except C
        print("C")
    except B
        print("B")

Note that if the except clauses were reversed (with first), it
would have printed B, B, B — the first matching except clause is triggered.

The last except clause may omit the exception name(s), to serve as a wildcard.
Use this with extreme caution, since it is easy to mask a real programming error
in this way! It can also be used to print an error message and then re-raise
the exception (allowing a caller to handle the exception as well):

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()[])
    raise

The … statement has an optional else
clause, which, when present, must follow all except clauses. It is useful for
code that must be executed if the try clause does not raise an exception. For
example:

for arg in sys.argv1:]:
    try
        f = open(arg, 'r')
    except OSError
        print('cannot open', arg)
    else
        print(arg, 'has', len(f.readlines()), 'lines')
        f.close()

The use of the clause is better than adding additional code to
the clause because it avoids accidentally catching an exception
that wasn’t raised by the code being protected by the …
statement.

When an exception occurs, it may have an associated value, also known as the
exception’s argument. The presence and type of the argument depend on the
exception type.

The except clause may specify a variable after the exception name. The
variable is bound to an exception instance with the arguments stored in
. For convenience, the exception instance defines
so the arguments can be printed directly without having to
reference . One may also instantiate an exception first before
raising it and add any attributes to it as desired.

>>> 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

If an exception has arguments, they are printed as the last part (‘detail’) of
the message for unhandled exceptions.

Exception handlers don’t just handle exceptions if they occur immediately in the
try clause, but also if they occur inside functions that are called (even
indirectly) in the try clause. For example:

8.6. User-defined Exceptions¶

Programs may name their own exceptions by creating a new exception class (see
for more about Python classes). Exceptions should typically
be derived from the class, either directly or indirectly.

Exception classes can be defined which do anything any other class can do, but
are usually kept simple, often only offering a number of attributes that allow
information about the error to be extracted by handlers for the exception. When
creating a module that can raise several distinct errors, a common practice is
to create a base class for exceptions defined by that module, and subclass that
to create specific exception classes for different error conditions:

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

Most exceptions are defined with names that end in “Error”, similar to the
naming of the standard exceptions.

User-Defined Exceptions

Python also allows you to create your own exceptions by deriving classes from the standard built-in exceptions.

Here is an example related to RuntimeError. Here, a class is created that is subclassed from RuntimeError. This is useful when you need to display more specific information when an exception is caught.

In the try block, the user-defined exception is raised and caught in the except block. The variable e is used to create an instance of the class Networkerror.

class Networkerror(RuntimeError):
   def __init__(self, arg):
      self.args = arg

So once you have defined the above class, you can raise the exception as follows −

try:
   raise Networkerror("Bad hostname")
except Networkerror,e:
   print e.args

Previous Page
Print Page

Next Page  

Лучшие практики вывода исключений

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

Не рекомендуется:

def bad_exception():
    try:
        raise ValueError('Intentional - do not want this to get caught')
        raise Exception('Exception to be handled')
    except Exception as error:
        print('Inside the except block: ' + repr(error))
        
bad_exception()

Вывод:

Inside the except block: ValueError('Intentional - do not want this to get caught',)

Рекомендуется:

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

try:
    raise ValueError('Testing exceptions: The input is in incorrect order', 'one', 'two', 'four') 
except ValueError as err:
    print(err.args)

Вывод:

 ('Testing exceptions: The input is in incorrect order', 'one', 'two', 'four')
Добавить комментарий

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

Adblock
detector