2012-12-14 26 views
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 

谢谢!

+0

你为什么没有'genOne'处理异常? – Blender

+0

在真正的问题中,我无法访问生成器。假设发电机不能修改,我可以轻易确定吗? – kaosad

回答

2

这可以推广到找到任意例外的起源的问题。使用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)。在您的特定示例中,您可能需要检查traceback.extract_tb(exc_traceback)阵列的任何元素中是否存在最低级别的生成器字符串genTwo

那些依赖于内部代码细节的硬编码检查已经被忽视了,尤其是,因为在你的特定示例中,你无法控制它们的实现。

+0

感谢您的建议。 – kaosad