Python — exceptions handling
Содержание:
- Summing Up
- Как обрабатывать исключения в Python?
- Some Built-In Exception Classes
- Handling Multiple Exceptions with Except
- Assertions in Python
- Base classes¶
- Exception hierarchy¶
- Как лучше выбирать элементы из списка?
- Exceptions in Python
- Типы исключений
- try/except/finally¶
- Base classes¶
- Raising an Exceptions
- Example: User-Defined Exception in Python
- Вложенные попробовать за исключением блоков пример
- Предупреждения¶
- Важные моменты обработки исключений
- Оператор finally
- Обработка исключений в Python
- 8.3. Handling Exceptions¶
- The Standard Exception Hierarchy
- Python try…finally
Summing Up
After seeing the difference between syntax errors and exceptions, you learned about various ways to raise, catch, and handle exceptions in Python. In this article, you saw the following options:
- allows you to throw an exception at any time.
- enables you to verify if a certain condition is met and throw an exception if it isn’t.
- In the clause, all statements are executed until an exception is encountered.
- is used to catch and handle the exception(s) that are encountered in the try clause.
- lets you code sections that should run only when no exceptions are encountered in the try clause.
- enables you to execute sections of code that should always run, with or without any previously encountered exceptions.
Free PDF Download: Python 3 Cheat Sheet
Как обрабатывать исключения в Python?
Давайте посмотрим на пример.
def divide(x, y): print(f'{x}/{y} is {x / y}') divide(10, 2) divide(10, 0) divide(10, 4)
Если мы запустим указанную выше программу, мы получим следующий результат.
10/2 is 5.0 Traceback (most recent call last): File "/Users/pankaj/Documents/PycharmProjects/PythonTutorialPro/hello-world/exception_handling.py", line 6, in <module> divide(10, 0) File "/Users/pankaj/Documents/PycharmProjects/PythonTutorialPro/hello-world/exception_handling.py", line 2, in divide print(f'{x}/{y} is {x / y}') ZeroDivisionError: division by zero
Второй вызов функции div() вызвал исключение ZeroDivisionError, и программа завершилась.
Давайте перепишем метод div() с правильной обработкой исключений. Если кто-то попытается разделить на 0, мы перехватим исключение и выведем сообщение об ошибке. Таким образом, программа не завершится преждевременно, и вывод будет более понятным.
def divide(x, y): try: print(f'{x}/{y} is {x / y}') except ZeroDivisionError as e: print(e) divide(10, 2) divide(10, 0) divide(10, 4)
Вывод:
10/2 is 5.0 division by zero 10/4 is 2.5
Some Built-In Exception Classes
Some of the built-in exception classes in Python are:
- ArithmeticError – this is the base class for arithmetic errors.
- AssertionError – raised when an assertion fails.
- AttributeError – when the attribute is not found.
- BufferError
- EOFError – reading after end of file
- ImportError – when the imported module is not found.
- LookupError – base exception for lookup errors.
- MemoryError – when out of memory occurs
- NameError – when a name is not found globally.
- OSError – base class for I/O errors
- ReferenceError
- RuntimeError
- StopIteration, StopAsyncIteration
- SyntaxError – invalid syntax
- SystemError – internal error in the Python Interpreter.
- TypeError – invalid argument type
- ValueError – invalid argument value
Handling Multiple Exceptions with Except
We can define multiple exceptions with the same except clause. It means that if the Python interpreter finds a matching exception, then it’ll execute the code written under the except clause.
In short, when we define except clause in this way, we expect the same piece of code to throw different exceptions. Also, we want to take the same action in each case.
Please refer to the below example.
Example
try: You do your operations here; ...................... except(Exception1]]): If there is any exception from the given exception list, then execute this block. ...................... else: If there is no exception then execute this block
Assertions in Python
An assertion is a sanity-check that you can turn on or turn off when you are done with your testing of the program.
-
The easiest way to think of an assertion is to liken it to a raise-if statement (or to be more accurate, a raise-if-not statement). An expression is tested, and if the result comes up false, an exception is raised.
-
Assertions are carried out by the assert statement, the newest keyword to Python, introduced in version 1.5.
-
Programmers often place assertions at the start of a function to check for valid input, and after a function call to check for valid output.
The assert Statement
When it encounters an assert statement, Python evaluates the accompanying expression, which is hopefully true. If the expression is false, Python raises an AssertionError exception.
The syntax for assert is −
assert Expression
If the assertion fails, Python uses ArgumentExpression as the argument for the AssertionError. AssertionError exceptions can be caught and handled like any other exception, using the try-except statement. If they are not handled, they will terminate the program and produce a traceback.
Example
Here is a function that converts a given temperature from degrees Kelvin to degrees Fahrenheit. Since 0° K is as cold as it gets, the function bails out if it sees a negative temperature −
#!/usr/bin/python3 def KelvinToFahrenheit(Temperature): assert (Temperature >= 0),"Colder than absolute zero!" return ((Temperature-273)*1.8)+32 print (KelvinToFahrenheit(273)) print (int(KelvinToFahrenheit(505.78))) print (KelvinToFahrenheit(-5))
When the above code is executed, it produces the following result −
32.0 451 Traceback (most recent call last): File "test.py", line 9, in <module> print KelvinToFahrenheit(-5) File "test.py", line 4, in KelvinToFahrenheit assert (Temperature >= 0),"Colder than absolute zero!" AssertionError: Colder than absolute zero!
Base classes¶
The following exceptions are used mostly as base classes for other exceptions.
- exception
-
The base class for all built-in exceptions. It is not meant to be directly
inherited by user-defined classes (for that, use ). If
is called on an instance of this class, the representation of
the argument(s) to the instance are returned, or the empty string when
there were no arguments.-
The tuple of arguments given to the exception constructor. Some built-in
exceptions (like ) expect a certain number of arguments and
assign a special meaning to the elements of this tuple, while others are
usually called only with a single string giving an error message.
- (tb)
-
This method sets tb as the new traceback for the exception and returns
the exception object. It is usually used in exception handling code like
this:try ... except SomeException tb = sys.exc_info()[2 raise OtherException(...).with_traceback(tb)
-
- exception
-
All built-in, non-system-exiting exceptions are derived from this class. All
user-defined exceptions should also be derived from this class.
- exception
-
The base class for those built-in exceptions that are raised for various
arithmetic errors: , ,
.
- exception
-
Raised when a related operation cannot be
performed.
Exception hierarchy¶
The class hierarchy for built-in exceptions is:
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
Как лучше выбирать элементы из списка?
Если вы хотите продуктивно работать со списками, то должны уметь получать доступ к данным, хранящимся в них.
Обычно мы получаем доступ к элементам списков, чтобы изменять определенные значения, обновлять или удалять их, или выполнять какие-либо другие операции с ними. Мы получаем доступ к элементам списков и, собственно, ко всем другим типам последовательностей, при помощи оператора индекса . Внутри него мы помещаем целое число.
# Выбираем первый элемент списка oneZooAnimal = biggerZoo # Выводим на экран переменную `oneZooAnimal` print(oneZooAnimal)
Запустите данный код и убедитесь, что вы получите первый элемент списка, сохраненного в переменную . Это может быть поначалу несколько непривычно, но нумерация начинается с числа , а не .
Как получить последний элемент списка?
Ответ на этот вопрос является дополнением к объяснению в предыдущем разделе.
Попробуйте ввести отрицательное значение, например, или , в оператор индекса, чтобы получить последние элементы нашего списка !
# Вставляем -1 monkeys = biggerZoo print(monkeys) # А теперь -2 zebra = biggerZoo print(zebra)
Не правда ли, не слишком сложно?
Что означает ошибка «Index Out Of Range»?
Эта ошибка одна из тех, которые вы будете видеть достаточно часто, особенно если вы новичок в программировании.
Лучший способ понять эту ошибку — попробовать ее получить самостоятельно.
Возьмите ваш список и передайте в оператор индекса либо очень маленькое отрицательное число, либо очень большое положительное число.
Как видите, вы можете получить ошибку «Индекс вне диапазона» в случаях, когда вы передаете в оператор индекса целочисленное значение, не попадающее в диапазон значений индекса списка. Это означает, что вы присваиваете значение или ссылаетесь на (пока) несуществующий индекс.
Срезы в списках
Если вы новичок в программировании и в Python, этот вопрос может показаться одним из наиболее запутанных.
Обычно нотация срезов используется, когда мы хотим выбрать более одного элемента списка одновременно. Как и при выборе одного элемента из списка, мы используем двойные скобки. Отличие же состоит в том, что теперь мы еще используем внутри скобок двоеточие. Это выглядит следующим образом:
# Используем нотацию срезов someZooAnimals = biggerZoo # Выводим на экран то, что мы выбрали print(someZooAnimals) # Теперь поменяем местами 2 и двоеточие otherZooAnimals = biggerZoo # Выводим на экран полученный результат print(otherZooAnimals)
Вы можете видеть, что в первом случае мы выводим на экран список начиная с его элемента , который имеет индекс . Иными словами, мы начинаем с индекса и идем до конца списка, так как другой индекс не указан.
Что же происходит во втором случае, когда мы поменяли местами индекс и двоеточие? Вы можете видеть, что мы получаем список из двух элементов, и . В данном случае мы стартуем с индекса и доходим до индекса (не включая его). Как вы можете видеть, результат не будет включать элемент .
В общем, подводя итоги:
# элементы берутся от start до end (но элемент под номером end не входит в диапазон!) a # элементы берутся начиная со start и до конца a # элементы берутся с начала до end (но элемент под номером end не входит в диапазон!) a
Совет: передавая в оператор индекса только двоеточие, мы создаем копию списка.
В дополнение к простой нотации срезов, мы еще можем задать значение шага, с которым будут выбираться значения. В обобщенном виде нотация будет иметь следующий вид:
# Начиная со start, не доходя до end, с шагом step a
Так что же по сути дает значение шага?
Ну, это позволяет вам буквально шагать по списку и выбирать только те элементы, которые включает в себя значение вашего шага. Вот пример:
Обратите внимание, что если вы не указали какое-либо значение шага, оно будет просто установлено в значение . При проходе по списку ни один элемент пропущен не будет
Также всегда помните, что ваш результат не включает индекс конечного значения, который вы указали в записи среза!
Как случайным образом выбрать элемент из списка?
Для этого мы используем пакет .
# Импортируем функцию `choice` из библиотеки `random` from random import choice # Создадим список из первых четырех букв алфавита list = # Выведем на экран случайный элемент списка print(choice(list))
Если мы хотим выбрать случайный элемент из списка по индексу, то можем использовать метод из той же библиотеки .
# Импортируем функцию `randrange` из библиотеки `random` from random import randrange # Создадим список из первых четырех букв алфавита randomLetters = # Выбираем случайный индекс нашего списка randomIndex = randrange(0,len(randomLetters)) # Выводим случайный элемент на экран print(randomLetters)
Совет: обратите внимание на библиотеку , она может вам пригодиться во многих случаях при программировании на Python
Exceptions in Python
Python has many built-in exceptions that are raised when your program encounters an error (something in the program goes wrong).
When these exceptions occur, the Python interpreter stops the current process and passes it to the calling process until it is handled. If not handled, the program will crash.
For example, let us consider a program where we have a function that calls function , which in turn calls function . If an exception occurs in function but is not handled in , the exception passes to and then to .
If never handled, an error message is displayed and our program comes to a sudden unexpected halt.
Типы исключений
- SyntaxError — Ошибка в синтаксисе программы
- NameError — Ошибка обращения к несуществующей переменной
- AttributeError — Ссылка на атрибут не работает
- TypeError — Операнд не имеет правильного типа
- ValueError — Неверный тип у значения переменной
- IOError — Ошибка в подсистеме системе ввода вывода
- ZeroDivisionError — Ошибка деления на ноль
Ознакомиться с полным списком встроенных исключений можно в официальной документации.
Этот пример кода выполняет деление одного числа на другое. Чтобы продемонстрировать ошибку, предположим что пользователь вводит 10 и 0 в качестве первого и второго чисел соответственно, Python на это возбуждает исключение ZeroDivisionError:
try/except/finally¶
Блок finally — это еще один опциональный блок в конструкции try. Он
выполняется всегда, независимо от того, было ли исключение или нет.
Сюда ставятся действия, которые надо выполнить в любом случае. Например,
это может быть закрытие файла.
Файл divide_ver4.py с блоком finally:
# -*- coding: utf-8 -*- try a = input("Введите первое число: ") b = input("Введите второе число: ") result = int(a)int(b) except (ValueError, ZeroDivisionError): print("Что-то пошло не так...") else print("Результат в квадрате: ", result**2) finally print("Вот и сказочке конец, а кто слушал - молодец.")
Проверка:
Base classes¶
The following exceptions are used mostly as base classes for other exceptions.
- exception
-
The base class for all built-in exceptions. It is not meant to be directly
inherited by user-defined classes (for that, use ). If
is called on an instance of this class, the representation of
the argument(s) to the instance are returned, or the empty string when
there were no arguments.-
The tuple of arguments given to the exception constructor. Some built-in
exceptions (like ) expect a certain number of arguments and
assign a special meaning to the elements of this tuple, while others are
usually called only with a single string giving an error message.
- (tb)
-
This method sets tb as the new traceback for the exception and returns
the exception object. It is usually used in exception handling code like
this:try ... except SomeException tb = sys.exc_info()[2 raise OtherException(...).with_traceback(tb)
-
- exception
-
All built-in, non-system-exiting exceptions are derived from this class. All
user-defined exceptions should also be derived from this class.
- exception
-
The base class for those built-in exceptions that are raised for various
arithmetic errors: , ,
.
- exception
-
Raised when a related operation cannot be
performed.
Raising an Exceptions
You can raise exceptions in several ways by using the raise statement. The general syntax for the raise statement is as follows.
Syntax
raise ]]
Here, Exception is the type of exception (for example, NameError) and argument is a value for the exception argument. The argument is optional; if not supplied, the exception argument is None.
The final argument, traceback, is also optional (and rarely used in practice), and if present, is the traceback object used for the exception.
Example
An exception can be a string, a class or an object. Most of the exceptions that the Python core raises are classes, with an argument that is an instance of the class. Defining new exceptions is quite easy and can be done as follows −
def functionName( level ): if level < 1: raise "Invalid level!", level # The code below to this would not be executed # if we raise the exception
Note: In order to catch an exception, an «except» clause must refer to the same exception thrown either class object or simple string. For example, to capture above exception, we must write the except clause as follows −
try: Business Logic here... except "Invalid level!": Exception handling here... else: Rest of the code here...
Example: User-Defined Exception in Python
In this example, we will illustrate how user-defined exceptions can be used in a program to raise and catch errors.
This program will ask the user to enter a number until they guess a stored number correctly. To help them figure it out, a hint is provided whether their guess is greater than or less than the stored number.
Here is a sample run of this program.
Enter a number: 12 This value is too large, try again! Enter a number: 0 This value is too small, try again! Enter a number: 8 This value is too small, try again! Enter a number: 10 Congratulations! You guessed it correctly.
We have defined a base class called .
The other two exceptions ( and ) that are actually raised by our program are derived from this class. This is the standard way to define user-defined exceptions in Python programming, but you are not limited to this way only.
Вложенные попробовать за исключением блоков пример
Мы можем вложить попробовать, кроме блоков в Python. В этом случае, если исключение поднимается в вложенном блоке TRY, вложенный кроме блока используется для обработки его. В случае, если вложенные за исключением не умеют обращаться с ним, внешние за исключением блоков используются для обработки исключения.
x = 10 y = 0 try: print("outer try block") try: print("nested try block") print(x / y) except TypeError as te: print("nested except block") print(te) except ZeroDivisionError as ze: print("outer except block") print(ze)
Выход:
outer try block nested try block outer except block division by zero
Предупреждения¶
Следующие исключения — используемый как предупреждение категорий; для получения
дополнительной информации см. документацию по .
- exception
-
Базовый класс для категорий предупреждений.
- exception
-
Базовый класс для предупреждений, генерируемых пользователем код.
- exception
-
Базовый класс для предупреждений об устаревших функциях, когда эти
предупреждения предназначены для других разработчиков Python.
- exception
-
Базовый класс для предупреждений об устаревших элементах, которые, как
ожидается, устареют в будущем, но не устарели в данный момент.Этот класс редко — используемый, поскольку испускание предупреждения о возможном
предстоящем осуждении необычно, и предпочтен для уже активных
осуждений.
- exception
-
Базовый класс для предупреждений о сомнительном синтаксисе.
- exception
-
Базовый класс для предупреждений о сомнительном поведении во время выполнения.
- exception
-
Базовый класс для предупреждений об устаревших функциях, когда эти
предупреждения предназначены для конечных пользователей приложений, написанных
на языке Python.
- exception
-
Базовый класс для предупреждений о возможных ошибках при импорте модулей.
- exception
-
Базовый класс для предупреждений, связанных с юникодом.
- exception
-
Базовый класс для предупреждений, связанных с и .
Важные моменты обработки исключений
Для прохождения профессионального проекта в python вам нужно быть осторожным с исключениями. Простое исключение может испортить ваш код. Итак, вам нужно обрабатывать эти исключения. Ниже приведены несколько важных моментов, касающихся обработки исключений:
- Подозрительный код лучше окружить try-except.
- Лучше использовать один блок try-except для одной строки подозрительного кода, чем использовать один блок try-except для блока подозрительного кода.
- Лучше отловить конкретный класс исключения. Использование обобщенного класса исключений не так уж и полезно для обработки.
Оператор finally
Оператор finally очень прост в использовании. Давайте взглянем на нижеизложенный пример:
Python
my_dict = {«a»:1, «b»:2, «c»:3}
try:
value = my_dict
except KeyError:
print(«A KeyError occurred!»)
finally:
print(«The finally statement has executed!»)
1 2 3 4 5 6 7 8 |
my_dict={«a»1,»b»2,»c»3} try value=my_dict»d» exceptKeyError print(«A KeyError occurred!») finally print(«The finally statement has executed!») |
Если вы запустите это код, оно отобразиться и в операторе except и в finally. Весьма просто, не так ли? Теперь вы можете использовать оператор finally, чтобы убрать за собой. Вы можете также вписать код exit в конце оператора finally.
Обработка исключений в Python
Язык имеет встроенную конструкцию для работы с исключениями. Обработка происходит с помощью блока try-except.
Блок try-except заставляет Python выполнить код внутри него, но также говорит Python, что делать в случае если будет вызвано исключение. Когда используете try-except, программа будет продолжать работать, даже если возникнут какие-нибудь ошибки. Вместо Traceback, который сбивает с толку, пользователи увидят дружественные сообщения об ошибках, но их нужно заранее предусмотреть.
Давайте введем тот же набор данных что и посмотрим что будет
Ввод строки вместо числа
В предыдущем примере деление на 0 приводило к исключению ZeroDivisionError, но когда ввели строковое значение переменной и попробовали на него разделить число сработало новое исключение ValueError.
Проверка с корректным вводом.
В этом примере не происходит вызова исключений т.к данные введены и обработаны корректно.
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:
The Standard Exception Hierarchy
Behold the standard exception hierarchy. It is defined in the new
standard library module exceptions.py. Exceptions that were new since
Python 1.5 are marked with (*).
The root class for all exceptions is the new exception Exception.
From this, two additional classes are derived, StandardError, which is
the root class for all standard exceptions, and SystemExit. It is
recommended that user-defined exceptions in new code be derived from
Exception, although for backward compatibility reasons, this is not
required. Eventually this rule will be tightened.
SystemExit is derived from Exception because while it is an
exception, it is not an error.
Most standard exceptions are direct descendants of StandardError.
Some related exceptions are grouped together using an intermediate
class derived from StandardError; this makes it possible to catch
several different exceptions in one except clause, without using the
tuple notation.
We looked into introducing more groups of related exceptions,
but couldn’t decide on the best grouping. In a language as dynamic as
Python, it’s hard to say whether TypeError is a «program error», a
«runtime error» or an «environmental error», so we decided to leave it
undecided. It could be argued that NameError and AttributeError
should be derived from LookupError, but this is questionable and
depends entirely on the application.
Exception Class Definitions
The Python class definitions for the standard exceptions are
imported from the standard module «exceptions». You can’t change this
file thinking that the changes will automatically show up in the
standard exceptions; the builtin module expects the current hierarchy
as defined in exceptions.py.
Details on the standard exception classes are available in the
Python library reference manual’s entry for the
exceptions module.
Python try…finally
The statement in Python can have an optional clause. This clause is executed no matter what, and is generally used to release external resources.
For example, we may be connected to a remote data center through the network or working with a file or a Graphical User Interface (GUI).
In all these circumstances, we must clean up the resource before the program comes to a halt whether it successfully ran or not. These actions (closing a file, GUI or disconnecting from network) are performed in the clause to guarantee the execution.
Here is an example of file operations to illustrate this.
This type of construct makes sure that the file is closed even if an exception occurs during the program execution.