Продолжить в течение l oop после пойманного исключения - PullRequest
0 голосов
/ 20 марта 2020

Я читаю большой (2 ГБ) файл через csv.DictReader (для чего это важно). Где-то глубоко в файле есть проблема с кодировкой, и я получаю UnicodeDecodeError. Глядя на сообщение об ошибке, я вижу, что ошибка возникает в неявном __next__ в моем for l oop.

Заглушка кода будет выглядеть следующим образом:

import csv

with open("myfile.csv", newline="") as f:
    c = csv.DictReader(f)
    for line in c: # here the error is happening
       pass

Я хочу использовать шаблон try-except для обнаружения любой ошибки чтения, записи значимого сообщения и продолжения чтения файла.

Как я мог этого достичь? Я не могу использовать continue вне l oop (то есть в блоке except), поэтому я думаю, что мне нужно было бы переписать for l oop, чтобы не использовать неявную форму, а явную, но поскольку я довольно новичок в python, я не знаю, как это сделать наиболее pythoni c способом.


Чтобы смоделировать ошибку, посмотрите на следующий пример игрушки:

class MyIterator:
    def __init__(self, mclass):
        self._mclass = mclass
        self._index = 0

    def __next__(self):
        if self._index == 3:
            # simulate an error in a file read
            self._index += 1
            raise Exception("simulated error"
        elif self._index < 5:
            self._index += 1
            return self._index - 1
        # End of Iteration
        raise StopIteration


class MyClass:
    def __iter__(self):
        return MyIterator(self)

obj = MyClass()
try:
    for result in obj:
        print(result)
except Exception as e:
    print("Exception covered")
    ## does not work for obvious reasons:
    # continue

Ответы [ 3 ]

1 голос
/ 23 марта 2020

Просто для записи, вместо попытки отловить ошибку на next, можно передать аргумент errors в open, который точно определяет, как обращаться с ошибками кода c.

0 голосов
/ 20 марта 2020

Какую python версию вы используете? Кроме того, почему бы не использовать yield (см. введите здесь описание ссылки )

Вы можете вернуться вместо повышения. Если вы знаете, является ли тип (переменная) исключением, вы можете обрабатывать информацию.

0 голосов
/ 20 марта 2020

Оберните ваш объект в iter и через некоторое время вызовите следующий объект l oop

done = False
obj = iter(MyClass())
while not done:
    try:
        data = next(obj)
    except StopIteration:
        done = True
    except Exception:
         print("process error here and continue")
...