0

我遇到了一种情况,我需要在我的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

谢谢!

4

1 回答 1

2

This can be generalized to the problem of finding the origin of an arbitrary exception.

Use the traceback module to inspect the stacktrace of your exception object.

Here is a previous answer on a similar subject.

Some example code:

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])

Shell output:

> ./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)')

Note that the [-1] in the extract_tb() call explicitly checks only the first lower level of the stacktrace. With the print you can see which element of that output you'd need to check (genOne -> item index #2 in that list). In your particular example you'd probably want to check if the lowest level generator string genTwo exists in any of the elements of the traceback.extract_tb(exc_traceback) array.

Those hardcoded checks relying on internal code details are been frowned upon, especially since in your particular example you do not have control over their implementation.

于 2012-12-14T13:26:00.527 回答