Obsługuj wyjątki generatora w swoim kliencie
To jest kontynuacjaObsługuj wyjątek zgłoszony w generatorze i omawia bardziej ogólny problem.
Mam funkcję, która odczytuje dane w różnych formatach. Wszystkie formaty są zorientowane liniowo lub rekordowo, a dla każdego formatu jest dedykowana funkcja parsowania, zaimplementowana jako generator. Główna funkcja odczytu pobiera dane wejściowe i generator, który odczytuje odpowiedni format z wejścia i dostarcza rekordy do głównej funkcji:
def read(stream, parsefunc):
for record in parsefunc(stream):
do_stuff(record)
gdzieparsefunc
to coś w stylu:
def parsefunc(stream):
while not eof(stream):
rec = read_record(stream)
do some stuff
yield rec
Problem, przed którym stoję, jest taki samparsefunc
może rzucić wyjątek (np. podczas odczytu ze strumienia), nie ma pojęcia, jak sobie z tym poradzić. Główną jest funkcja odpowiedzialna za obsługę wyjątkówread
funkcjonować. Należy zauważyć, że wyjątki występują na podstawie rekordów, więc nawet jeśli jeden rekord zawiedzie, generator powinien kontynuować swoją pracę i odzyskać rekordy, aż cały strumień zostanie wyczerpany.
W poprzednim pytaniu próbowałem to umieścićnext(parsefunc)
wtry
blok, ale jak się okazało, to nie zadziała. Więc muszę dodaćtry-except
doparsefunc
sam, a następnie jakoś dostarczać wyjątki konsumentowi:
def parsefunc(stream):
while not eof(stream):
try:
rec = read_record()
yield rec
except Exception as e:
?????
Jestem raczej niechętny, aby to zrobić, ponieważ
nie ma sensu używaćtry
w funkcji, która nie jest przeznaczona do obsługi wyjątkównie jest dla mnie jasne, jak przekazywać wyjątki do funkcji konsumpcjibędzie wiele formatów i wieleparsefunc
Nie chcę zaśmiecać ich zbyt dużą ilością kodu pomocniczego.Czy ktoś sugeruje lepszą architekturę?
Uwaga dla pracowników Google: oprócz najwyższej odpowiedzi, zwróć uwagę nanadawcy iJona posty - bardzo inteligentne i wnikliwe rzeczy.