对空生成器做出反应的Pythonic方法?

时间:2020-09-21 07:58:54

标签: python python-3.x generator yield

我想为生成器编写一个包装器,以检查生成器是否产生任何东西,并且(例如)生成异常(如果没有)。

我可以写:

def my_wrapper(input):
    if input is None:
        return

    found = False
    for elem in my_yielding_function(input):
        found = True
        yield elem

    if not found:
        raise MyException("Empty Generator")

还有更多的Python方式可以做到这一点吗?

有一个非常similar question的地方,但是已经有10多年的历史了-也许情况已经改变了?

上下文

很难解释-我正在使用给定的API函数,该函数可能不会产生任何结果,但在这种情况下, my 函数与空输入有所区别。

1 个答案:

答案 0 :(得分:3)

除了避免了无用的for循环之外,还消除了标志的需要。您也可以将其用作装饰器,以使转发调用参数并仍然可重用

def check_if_empty_first(gen):
  it = gen() # This is optional, depends if you want to make it reusable, and it you want to call with check_if_empty_first(gen) or check_if_empty_first(gen())
  try:
    yield next(it)
  except StopIteration as e:
    raise MyException("Empty Generator") from e
  yield from it

装饰器版本:

from functools import wraps
def check_if_empty_first(gen):
  @wraps(gen)
  def inner(*args, **kwargs
    it = gen(*args, **kwargs)
    try:
      yield next(it)
    except StopIteration as e:
      raise MyException("Empty Generator") from e
    yield from it
  return inner