Продолжение выполнения кода 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?