"Deep return"一直回到第一个函数调用



假设我有两个(或更多(函数。一个是更高级别,通过调用不同的其他函数来处理东西。如果其中一个函数失败(例如数学错误(,我不仅要"中止"该函数,还要"中止"调用它的函数。就我而言,我需要它来逃避错误并避免在不退出整个过程的情况下完成其余所有计算(这也会终止我的 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))

当 10 除以x时,使用值 0 初始化x会导致levelB崩溃。所以我首先确保x不同于 0。如果不是,则通过调用 return 中止该函数。现在levelA想继续将levelB的结果加倍,在x=0的情况下,结果是"无",然后我们又开始了一次崩溃。

当然,我能做的是插入行

if xx is None: return

在做xx *= 2之前.但在我的真实案例中,不仅有一个额外的级别,而是 2 个甚至 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

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

当 10 除以 x 时,用值 0 初始化 x 会导致 levelB 崩溃。所以我首先确保 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?')

最新更新