当前位置: 首页 > 面试题库 >

在使用者中处理生成器异常

邬英武
2023-03-14
问题内容

这是处理生成器中引发的异常的后续操作,并讨论了一个更一般的问题。

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

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- exceptparsefunc自身,然后以某种方式提供例外的消费者:

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

我不太愿意这样做,因为

  • try在不打算处理任何异常的函数中使用没有意义
  • 我不清楚如何将异常传递给使用函数
  • 会有许多格式和许多格式parsefunc,我不想用太多的辅助代码来使它们混乱。

有没有人建议更好的架构


问题答案:

您可以在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


 类似资料:
  • 我有一个循环缓冲区(数组/先进先出),一个消费者和一个生产者。生产者将随机数放入数组中,消费者获取第一个数字并检查它是否是相对素数。 我的代码工作正常,我认为它工作正常,但我想改进它。我不太确定我的“空运行”方法。我应该在其他地方做异常处理吗?改变“无限循环”?不应更改方法签名(它们是预定义的)。 我会很高兴每一个改进代码的建议。(不在乎知名度(公开,...),还有静态的东西,我刚刚把它们放在一个

  • 问题内容: 我有一个生成器和一个使用它的函数: 如果生成器引发异常,我想在使用者函数中处理该异常,然后继续使用迭代器,直到耗尽为止。请注意,我不想在生成器中有任何异常处理代码。 我想到了类似的东西: 但这对我来说看起来很尴尬。 问题答案: 这也是我不确定是否正确/优雅处理的事情。 我要做的是从生成器中获取一个,然后将其提升到其他位置。喜欢: 这样,我仍然继承了Exception而没有引发它,这将导

  • 安装程序的问题是,Camel没有为调用我的自定义异常处理程序。路由SaveSample发生验证异常。下面是我的发现,它是如何进一步深入骆驼处理器类型的。 > 控件将转到中,在那里查找异常策略。失败exchange的根(即->postSample)在此应定义异常处理程序。 稍后,Camel转到failing(即saveSample)以标识异常处理程序。 这意味着,在下面的表达式中,routeId来自

  • 尝试在Micronaut 2.2.1中实现处理使用者异常https://micronaut-projects.github.io/micronaut-rabbitmq/latest/guide/#consumerexceptions 按照文件规定

  • 我目前正在尝试用Kotlin为Android编写一个注释处理器。项目结构如下: 项目/构建.gradle 注释/build.gradle 样品/build.gradle Annotation.kt AnnotationProcessor.kt 使用kapt,构建在示例javaPreCompileDebug上中断,并显示以下消息: 当我用注释处理器替换 kapt 时,构建在示例:转换类上中断了以下消

  • 我有一个REST控制器,它调用带有注释的网关(errorChannel=ERROR\u CHANNEL) 这样,无论下游发生什么错误,网关发起的集成流都将流入一个错误通道,该通道将由另一个集成流处理,这是按预期工作的。 现在,还有另一个场景,其中一个集成流从Kafka读取消息,将这些消息路由到另一个通道,另一个集成流处理这些消息,另一个流向远程服务发送HTTP请求。 如何处理上述流中可能出现的异常