Продолжение выполнения кода Python после исключения
Я пытаюсь считать все файлы из папки, соответствующие определённому критерию. Программа выдает ошибку и останавливается, как только возникает исключение. Я пытаюсь продолжить выполнение даже после возникновения исключения, но она всё равно прекращает выполнение.
Вот что я получаю через несколько секунд:
error <type 'exceptions.IOError'>
Вот мой код:
import os
path = 'Y:\\Files\\'
listing = os.listdir(path)
try:
for infile in listing:
if infile.startswith("ABC"):
fo = open(infile,"r")
for line in fo:
if line.startswith("REVIEW"):
print infile
fo.close()
except:
print "error "+str(IOError)
pass
Как я могу исправить код, чтобы он продолжал выполнять чтение остальных файлов, даже если возникает ошибка?
4 ответ(ов)
Ваше решение по размещению структуры try/except больше внутрь цикла является правильным. В противном случае, если возникнет ошибка, это прервет все циклы.
Рекомендуется разместить try/except после первого цикла for, чтобы при возникновении ошибки обработка продолжалась с следующим файлом. Таким образом, ваш код будет выглядеть следующим образом:
for infile in listing:
try:
if infile.startswith("ABC"):
fo = open(infile, "r")
for line in fo:
if line.startswith("REVIEW"):
print(infile)
fo.close()
except:
pass
Тем не менее, это отличный пример того, почему стоит использовать конструкцию with для открытия файлов. Если вы открываете файл с помощью open(), но возникает ошибка, файл останется открытым навсегда. Лучше сделать сейчас, чем никогда.
Вот исправленный пример с использованием with:
for infile in listing:
try:
if infile.startswith("ABC"):
with open(infile, "r") as fo:
for line in fo:
if line.startswith("REVIEW"):
print(infile)
except:
pass
Теперь, если произойдет ошибка, файл будет закрыт автоматически, что и делает конструкция with.
Ваш код делает именно то, что вы ему говорите. Когда возникает исключение, выполняется данная часть:
except:
print "error " + str(IOError)
pass
Так как после этого ничего не происходит, программа заканчивает свою работу.
Кроме того, ключевое слово pass здесь избыточно. Вы можете просто удалить его, и код останется работоспособным. Если вы хотите, чтобы программа продолжала выполнение после обработки ошибки, вам нужно добавить соответствующий код вместо pass.
Для того чтобы переместить блок try/except внутрь цикла for, вам нужно обернуть код, который может вызвать исключение, в этот блок. Вот как это можно сделать:
import os
path = 'C:\\'
listing = os.listdir(path)
for infile in listing:
try:
if infile.startswith("ABC"):
with open(infile, "r") as fo: # Используйте with для автоматического закрытия файла
for line in fo:
if line.startswith("REVIEW"):
print(infile)
except IOError as e: # Ловим конкретное исключение IOError
print("Ошибка при работе с файлом {}: {}".format(infile, e))
Здесь несколько изменений:
- Блок
tryтеперь находится внутри циклаfor, что позволяет обрабатывать исключения для каждого файла отдельно. - Используется конструкция
withдля открытия файла, что гарантирует его закрытие, даже если возникнет исключение. - Обработчик
exceptтеперь ловит конкретное исключениеIOError, что позволяет получить больше информации об ошибке.
Согласно строгой интерпретации вопроса "продолжать выполнение, даже если произошло исключение", Python предоставляет нам ключевое слово finally, которое выполняет блок кода независимо от того, что происходит перед ним. Единственная проблема с этим способом заключается в том, что он выполнит блок кода независимо от типа ошибки, что может быть не всегда желательно.
Вот пример на Python:
try:
unreal = 3 / 0 # вызывает исключение деления на ноль
print(unreal)
# обрабатываем исключение деления на ноль
except ZeroDivisionError:
print("Нельзя делить на ноль, у 0 нет мультипликативного обратного.")
finally:
# этот блок всегда выполняется
print("Брахмагута утверждал, что 'ноль, деленный на ноль, равен нулю'.")
В этом примере блок finally будет выполнен в любом случае, даже если возникает исключение. Обратите внимание на то, что мы также можем обрабатывать конкретные исключения, что позволяет нам более гибко управлять поведением программы.
Как изменить порядок столбцов в DataFrame?
'pip' не распознан как командa внутреннего или внешнего формата
Почему statistics.mean() работает так медленно?
Преобразование строки даты JSON в datetime в Python
Есть ли разница между поднятием экземпляра класса Exception и самого класса Exception?