关于python 3.x:如何确定哪个嵌套生成器产生StopIteration异常?

How to determine which nested generator produces StopIteration exception?

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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

谢谢!


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

使用traceback模块检查异常对象的stacktrace。

这是以前关于类似主题的答案。

一些示例代码:

1
2
3
4
5
6
7
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])

外壳输出:

1
2
3
4
5
6
7
8
9
10
11
> ./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]只显式检查stacktrace的第一个较低级别。通过打印,您可以看到需要检查输出的哪个元素(该列表中的genOne->item index 2)。在您的特定示例中,您可能希望检查traceback.extract_tb(exc_traceback)数组的任何元素中是否存在最低级别的生成器字符串genTwo

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