Сообщить об ошибке.

Использование finally в конструкции с try.

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

try:
    raise KeyboardInterrupt
finally:
    print('Goodbye, world!')

# Goodbye, world!
# KeyboardInterrupt
# Traceback (most recent call last):
#   File "<stdin>", line 2, in <module>

Если инструкция finally присутствует, то она будет выполняться как последняя задача перед завершением выполнения конструкции try. Инструкция finally выполняется независимо от того, создает ли блок кода в операторе try исключение. В следующих пунктах рассматриваются более сложные случаи, когда возникает исключение:

  • Если исключение возникает во время выполнения инструкции try, исключение может быть обработано инструкцией except. Если исключение не обрабатывается предложением except, исключение повторно вызывается после выполнения инструкции finally.
  • Исключение может возникнуть во время выполнения инструкции except или else конструкции try. Опять же, исключение повторно вызывается после выполнения инструкции finally.
  • Если в блоке кода инструкции try имеется оператор break, continue или return, инструкция finally будет выполняться непосредственно перед выполнением оператора break, continue или return.
  • Если оператор return имеется в инструкции try и finally, то оператор return в инструкции finally выполнится последним, т. е. вместо return, который в инструкции try.

Например:

def bool_return():
    try:
        return True
    finally:
        return False

>>> bool_return()
# False

Более сложный пример:

def divide(x, y):
    try:
        result = x / y
    except ZeroDivisionError:
        print("division by zero!")
    else:
        print("result is", result)
    finally:
        print("executing finally clause")

>>> divide(2, 1)
# result is 2.0
# executing finally clause

>>> divide(2, 0)
# division by zero!
# executing finally clause

>>> divide("2", "1")
# executing finally clause
# Traceback (most recent call last):
#   File "<stdin>", line 1, in <module>
#   File "<stdin>", line 3, in divide
# TypeError: unsupported operand type(s) for /: 'str' and 'str'

Как видно из примеров, инструкция finally выполняется в любом случае. TypeError, вызванный разделением двух строк, не обрабатывается предложением except и поэтому повторно вызывается после выполнения предложения finally.

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