这是对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块中,但事实证明,这是行不通的。因此,我必须将try-except添加到parsefunc本身,然后以某种方式将异常传递给消费者:
def parsefunc(stream):
while not eof(stream):
try:
rec = read_record()
yield rec
except Exception as e:
?????我很不愿意这么做,因为
try是没有意义的parsefunc,我不想让它们被太多的辅助代码所干扰。有没有人建议更好的建筑?
谷歌员工注意:除了上面的答案,还要注意senderle's和Jon's的帖子--非常聪明和有洞察力的东西。
发布于 2012-07-06 19:20:47
关于将异常从生成器传播到消费函数的要点,可以尝试使用错误代码(一组错误代码)来指示错误。虽然不是很优雅,但这是您可以想到的一种方法。
例如,在下面的代码中,产生一个类似于-1的值,当您期望一组正整数时,会向调用函数发出一个错误信号。
In [1]: def f():
...: yield 1
...: try:
...: 2/0
...: except ZeroDivisionError,e:
...: yield -1
...: yield 3
...:
In [2]: g = f()
In [3]: next(g)
Out[3]: 1
In [4]: next(g)
Out[4]: -1
In [5]: next(g)
Out[5]: 3https://stackoverflow.com/questions/11366892
复制相似问题