finally в одном блоке try. finally всегда выполняется последним, независимо от того, произошло исключение или нет. Если требуется несколько этапов очистки, можно вложить try...finally блоки друг в друга, либо использовать контекстные менеджеры (with).
В Python невозможно непосредственно использовать несколько блоков finally подряд для одного и того же блока try. Синтаксис Python позволяет только один блок finally на каждый блок try.
Однако, можно достичь похожего эффекта, вкладывая конструкции try...finally друг в друга. Каждый finally блок гарантированно выполнится, независимо от того, было ли исключение в соответствующем блоке try или нет. Этот подход позволяет обеспечить выполнение нескольких наборов "очищающих" действий.
Вот пример, демонстрирующий вложенные try...finally конструкции:
try:
# Первый блок try: Здесь может произойти исключение.
resource1 = open("file1.txt", "w")
try:
# Второй блок try: Вложенный.
resource2 = open("file2.txt", "w")
try:
# Код, который может вызвать исключение.
resource2.write("Some data")
#raise Exception("Example Exception") # Раскомментируйте для симуляции исключения
finally:
# Закрытие resource2 гарантированно.
print("Закрываем resource2")
resource2.close()
finally:
# Закрытие resource1 гарантированно.
print("Закрываем resource1")
resource1.close()
except Exception as e:
print(f"Произошло исключение: {e}")
Пояснения:
resource1 и resource2 представляют собой ресурсы, которые необходимо освободить (например, закрыть файлы).try пытается открыть file1.txt. Его блок finally гарантирует закрытие этого файла.try пытается открыть file2.txt и произвести запись в него. Его блок finally гарантирует закрытие этого файла.try, сначала выполняется finally внутреннего блока (закрывается resource2), затем исключение "всплывает" во внешний блок try, и выполняется его finally (закрывается resource1), после чего исключение обрабатывается в блоке except.resource1, то finally блок для resource1 сработает, но внутренний блок try не будет выполнен.finally все равно будут выполнены.Такая вложенность обеспечивает гарантию освобождения ресурсов, даже если в коде возникают исключения. Это важный паттерн для написания надежного кода на Python.
Альтернативы (менее предпочтительные для этой конкретной задачи, но полезные для знания):
with statement): Наиболее рекомендуемый способ работы с ресурсами, требующими освобождения. Он автоматически вызывает методы __enter__ и __exit__ объекта, что упрощает и делает код чище. Применимо, если ресурс поддерживает протокол контекстного менеджера.finally. Это приводит к ухудшению читаемости и усложнению поддержки кода.