2017-08-28 103 views
3

假设我有两个(或更多)函数。一个是更高层次的,通过调用不同的其他功能处理东西。如果其中一个函数失败(例如数学错误),我想“中止”不仅是该函数,还有那些调用它的函数。在我的情况下,我需要这个来避免错误,并避免完成所有计算的其余部分,而不必退出整个过程(这也会终止我的GUI)。相反,我希望脚本能够继续运行,但回到最上层。“深度返回”返回第一个函数调用

这是我原来的问题的抽象:

def levelA(x): 
    xx = levelB(x=x) 
    xx *= 2 
    return xx 

def levelB(x): 
    if x==0: return 
    y = 10/x 
    return y 

x = 0 
print (levelA(x=x)) 

初始化x值为0将导致levelB崩溃时10由x分。所以我首先确定x与0不同。如果不是,则函数通过调用return返回。现在levelA想要继续将levelB的结果翻倍,在x=0的情况下,结果为“无”,并且我们还有另一次崩溃。

当然,有什么我能做的就是做xx *= 2之前插入线

if xx is None: return 

。但在我的实际情况中,不仅有一个额外的级别,而且还有2个甚至3个,并且有很多不同的函数被调用。我想避免检查函数的每个输出是否有错误。

所以我的问题是:我可以以某种方式回到第一个函数调用,并跳过那些之间的?像“深度回报”?

+2

'try'和'除了''而不是'if'和'else'。这就是所谓的[EAFP](https://docs.python.org/3/glossary.html#term-eafp)。 :) – MSeifert

+0

抛出一个自定义异常,并在第一个函数中捕获它? –

+0

'if x == 0:return' this returns'None' and renders your first function invalid – Mangohero1

回答

3

例外被发明来处理你描述的情况。因此,例如:

In [72]: def f1(x): 
    ...:  return f2(x) 
    ...: 

In [73]: def f2(x): 
    ...:  return f3(x) 
    ...: 

In [74]: def f3(x): 
    ...:  if x > 0: 
    ...:   return x 
    ...:  else: 
    ...:   raise ValueError("f3 called with negative argument") 
    ...: 

In [75]: try: 
    ...:  print(f1(-2)) 
    ...: except ValueError as e: 
    ...:  print(e) 
    ...: 
f3 called with negative argument 
+0

您帖子中的重要提示是我可以用一个字符串和一个'ValueError' - 这是我错过的拼图。这意味着我基本上可以抓住所有东西,并给我自己的错误信息,这是我的主程序处理! – offeltoffel

+1

确实。如果你愿意,你甚至可以定义你自己的例外。 – holdenweb

+0

只是想告诉你,我在我的GUI构造函数中实现了ValueErrors,现在我捕获所有错误而不必退出强制它崩溃的应用程序。谢谢! – offeltoffel

3

try/catch怎么样?

def levelA(x): 
    xx = levelB(x=x) 
    xx *= 2 
    return xx 

def levelB(x): 
    if x==0: raise ZeroDivisionError 
    y = 10/x 
    return y 

try: 
    x = 0 
    print (levelA(x=x)) 
except ZeroDivisionError: 
    // error handling or other stuff 
1

初始化x,其中0值将导致在水平b崩溃时10被除以x。所以我首先确保x不等于0.如果不是,则函数通过调用return返回。

这是一个很好的总结,但你得出了错误的结论。你不应该return,你应该提出一个Exception。然后你可以使用一个tryexcept条款无论你要处理的是:

def levelA(x): 
    xx = levelB(x=x) 
    xx *= 2 
    return xx 

def levelB(x): 
    if x==0: raise ValueError 
    y = 10/x 
    return y 

x = 0 
try: 
    print(levelA(x=x)) 
except ValueError: 
    print('x was invalid! Wanna try again?') 

更妙的是只是做了分工,并捕获异常升高有:

def levelA(x): 
    xx = levelB(x=x) 
    xx *= 2 
    return xx 

def levelB(x): 
    y = 10/x 
    return y 

x = 0 
try: 
    print(levelA(x=x)) 
except ZeroDivisionError: 
    print('x was invalid! Wanna try again?') 
+0

我对try和try的概念很熟悉,特别是对于ZeroDivisionError。问题在于我的最高级别处理所有异常(而不是低级别)。这是我的GUI的类,它还包含弹出消息框的函数。在最底层的功能中,我没有这些可能性。所以我想要的是快速回到我的最高级别函数,该函数创建一个带有抛出错误的MessageBox。这也可能吗? – offeltoffel

+1

@offeltoffel如果你发现了这个例外,你在except语句中做的是由你决定的。您可以将'try'和'except'放入转发给函数的GUI代码中,并在except子句中弹出消息框。 – MSeifert