Python中的下一个函数是否发生故障?

时间:2017-03-14 15:32:19

标签: python generator

documentation所示,如果迭代器用尽,则返回默认值。但是,在下面的程序中,g(x)函数没有用完,我希望在下一个函数中不会处理来自f(x)的错误。

def f(x) :
    if 0 :  # to make sure that nothing is generated
        yield 10

def g(x) :
    yield next(f(x))

# list(g(3))
next(g(3), None)

我的期望:

Traceback (most recent call last):
  File "a.py", line 9, in <module>
    next(g(3), None)
  File "a.py", line 6, in g
    yield next(f(x))
StopIteration

我遇到的是程序运行成功。 我可以使用交替方法来实现目标吗?或者它可以在Python中修复?

编辑:上面提到的程序可能会像这样修改,以防止出现歧义。

def f(x) :
    if 0 :  # to make sure that nothing is generated
        yield 10

def g(x) :
    f(x).__next__()  # g(x) is not exhausted at this time
    yield 'something meaningful'
        # I hope that the next function will only catch this line

# list(g(3))
next(g(3), None)

2 个答案:

答案 0 :(得分:3)

带有默认参数的

next无论来源都会捕获StopIteration

您期望看到的行为,使用此代码可能会更好地理解:

def justraise():
    yield next(iter([])) # raises StopIteration

next(justraise(), None) # None
next(justraise()) # raises StopIteration

转到您的代码 - 即使内部使用的是next而没有默认参数,它引发的StopIteration也会使用默认参数在外部next中捕获。

如果你有一个有意义的异常引发,你应该引发一个有意义的异常而不是StopIteration,这表示迭代结束(而不是错误) - 这是next所依赖的。

答案 1 :(得分:-1)

g(x)是一个迭代器,总是产生f(x),产生Nothing,并引发StopIteration(在f中)

您可以检查next(f(some_value))在调用时是否会引发异常。

会一样

def g(x):
    return next(f(x))

但是,您已添加了默认None,因此g(x)将会运行,但只需返回None,因为迭代器已用完。

如果您删除None,则会看到

In [5]: next(g(3))
---------------------------------------------------------------------------
StopIteration                             Traceback (most recent call last)
<ipython-input-14-05eb86fce40b> in <module>()
----> 1 next(g(3))

<ipython-input-13-a4323284f776> in g(x)
      1 def g(x) :
----> 2     yield next(f(x))
      3

StopIteration: