gpt4 book ai didi

python - 在其消费者中处理生成器异常

转载 作者:太空宇宙 更新时间:2023-11-03 12:08:53 25 4
gpt4 key购买 nike

这是 Handle an exception thrown in a generator 的后续行动并讨论了一个更普遍的问题。

我有一个函数可以读取不同格式的数据。所有格式都是面向行或记录的,并且对于每种格式都有一个专用的解析函数,作为生成器实现。因此,主读取函数获得一个输入和一个生成器,生成器从输入中读取其各自的格式并将记录返回给主函数:

def read(stream, parsefunc):
for record in parsefunc(stream):
do_stuff(record)

parsefunc 是这样的:

def parsefunc(stream):
while not eof(stream):
rec = read_record(stream)
do some stuff
yield rec

我面临的问题是,虽然 parsefunc 可以抛出异常(例如,当从流中读取时),但它不知道如何处理它。负责处理异常的函数是主要的read函数。请注意,异常发生在每条记录的基础上,因此即使一条记录失败,生成器也应继续其工作并返回记录,直到整个流耗尽。

在上一个问题中,我尝试将 next(parsefunc) 放在 try block 中,但事实证明,这是行不通的。所以我必须将 try-except 添加到 parsefunc 本身,然后以某种方式将异常传递给消费者:

def parsefunc(stream):
while not eof(stream):
try:
rec = read_record()
yield rec
except Exception as e:
?????

我不太愿意这样做,因为

  • 在不打算处理任何异常的函数中使用try 是没有意义的
  • 我不清楚如何将异常传递给消费函数
  • 将会有很多格式和很多 parsefunc,我不想用太多的辅助代码把它们搞得一团糟。

有人对更好的架构有什么建议吗?

googlers注意事项:除了top answer,还要关注senderle'sJon's帖子 - 非常聪明和有见地的东西。

最佳答案

你可以在 parsefunc 中返回记录和异常的元组,让消费者函数决定如何处理异常:

import random

def get_record(line):
num = random.randint(0, 3)
if num == 3:
raise Exception("3 means danger")
return line


def parsefunc(stream):
for line in stream:
try:
rec = get_record(line)
except Exception as e:
yield (None, e)
else:
yield (rec, None)

if __name__ == '__main__':
with open('temp.txt') as f:
for rec, e in parsefunc(f):
if e:
print "Got an exception %s" % e
else:
print "Got a record %s" % rec

关于python - 在其消费者中处理生成器异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15136553/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com