这是后续处理生成器中抛出的异常 https://stackoverflow.com/q/11366064/989121并讨论一个更普遍的问题。
我有一个读取不同格式数据的函数。所有格式都是面向行或记录的,并且对于每种格式都有一个专用的解析函数,作为生成器实现。因此,主读取函数获取一个输入和一个生成器,生成器从输入中读取其各自的格式并将记录传递回主函数:
def read(stream, parsefunc):
for record in parsefunc(stream):
do_stuff(record)
where parsefunc
是这样的:
def parsefunc(stream):
while not eof(stream):
rec = read_record(stream)
do some stuff
yield rec
我面临的问题是parsefunc
可能会抛出异常(例如,从流中读取时),但它不知道如何处理它。负责处理异常的函数是mainread
功能。请注意,异常是在每条记录的基础上发生的,因此即使一条记录失败,生成器也应该继续其工作并返回记录,直到整个流耗尽。
在上一个问题中我试图提出next(parsefunc)
in a try
阻止,但事实证明,这是行不通的。所以我必须添加try-except
to the parsefunc
本身,然后以某种方式向消费者传递异常:
def parsefunc(stream):
while not eof(stream):
try:
rec = read_record()
yield rec
except Exception as e:
?????
我很不愿意这样做,因为
- 使用没有意义
try
在不打算处理任何异常的函数中
- 我不清楚如何将异常传递给消费函数
- 将会有很多格式和很多
parsefunc
的,我不想用太多的帮助代码让它们变得混乱。
有没有人建议更好的架构?
给谷歌用户的提示:除了最上面的答案之外,还要注意森德勒斯 https://stackoverflow.com/a/11419139/989121 and Jon's https://stackoverflow.com/a/12655987/989121帖子 - 非常聪明和有洞察力的东西。
您可以在 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
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)