【问题标题】:How to determine which nested generator produces StopIteration exception?如何确定哪个嵌套生成器产生 StopIteration 异常?
【发布时间】:2012-12-14 09:38:04
【问题描述】:

我遇到了一种情况,我需要在我的 try/except 代码中确定哪个嵌套生成器引发了 StopIteration 异常。我该怎么做?以下是一个虚拟示例:

def genOne(iMax, jMax):
    i = 0;
    g2 = genTwo(jMax)
    while i <= iMax:
        print('genOne: ' + str(i))
        next(g2)
        yield
        i = i + 1

def genTwo(jMax):
    j = 0;
    while j <= jMax:
        print('genTwo: ' + str(j))
        yield
        j = j + 1

g1 = genOne(6, 3)        # The inputs are arbitrary numbers
try:
    while True:
        next(g1)    
except:  
    # Do some processing depending on who generates the StopIteration exception

谢谢!

【问题讨论】:

  • 为什么不让genOne处理异常?
  • 在真正的问题中,我无法访问生成器。假设生成器不能修改,我可以轻松确定吗?

标签: python-3.x


【解决方案1】:

这可以推广到寻找任意异常的起源的问题。

使用traceback module 检查异常对象的堆栈跟踪。

这是一个类似主题的previous answer

一些示例代码:

g1 = genOne(6, 3)        # The inputs are arbitrary numbers
try:
    while True:
        next(g1)    
except:
    exc_type, exc_value, exc_traceback = sys.exc_info()
    print(traceback.extract_tb(exc_traceback)[-1])

外壳输出:

> ./test.py
genOne: 0
genTwo: 0
genOne: 1
genTwo: 1
genOne: 2
genTwo: 2
genOne: 3
genTwo: 3
genOne: 4
('./test.py', 12, 'genOne', 'next(g2)')

请注意,extract_tb() 调用中的[-1] 仅显式检查堆栈跟踪的第一个较低级别。通过打印,您可以看到需要检查该输出的哪个元素(genOne -> 该列表中的项目索引#2)。在您的特定示例中,您可能想要检查最低级别的生成器字符串 genTwo 是否存在于 traceback.extract_tb(exc_traceback) 数组的任何元素中。

那些依赖于内部代码细节的硬编码检查不受欢迎,尤其是,因为在您的特定示例中,您无法控制它们的实现。

【讨论】:

  • 感谢您的建议。
猜你喜欢
  • 2013-12-19
  • 2017-09-30
  • 2012-06-27
  • 1970-01-01
  • 2017-05-24
  • 2017-03-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多