蹦床函数本身不内置错误捕获能力,但可通过在while循环内对thunk()调用加try-except统一捕获所有递归层异常,异常堆栈变扁但信息可借上下文补充,多层嵌套异常和主动抛出均被同一处捕获。

蹦床函数本身不内置错误捕获能力,但它可以和 Python 的 try-except 机制自然协同——关键在于把异常抛出点控制在thunk 执行环节,而非递归调用栈深处。
蹦床函数里哪里能捕获异常
异常只能在 thunk 被实际调用时发生,而蹦床的 while 循环正是统一执行所有 thunk 的地方。这意味着:
- 所有递归步骤被“拍平”后,都变成一个函数对象(thunk)
- 这些 thunk 在循环中逐个调用,每一步都在同一栈帧内执行
- 因此,只要把
try-except套在 while 循环内部的thunk()调用处,就能捕获任意一层逻辑抛出的异常
例如:
def trampoline(f):
while callable(f):
try:
f = f() # 这里执行 thunk,可能抛出异常
except ZeroDivisionError as e:
print("除零错误,在某次计算中发生")
return None
except ValueError as e:
print("值错误,输入或转换出问题")
return None
return f
异常信息不会丢失,但堆栈变扁了
由于没有深层调用栈,traceback 不会显示层层嵌套的 fun_a → fun_b → fun_c,而是指向:
-
trampoline函数里的f()那一行 - 加上原始出错位置的
raise或运算(比如10 / 0)
你可以通过在 thunk 构造时附带上下文(如当前参数、步骤编号),或在 except 块中手动记录日志,来弥补堆栈变浅带来的调试信息缺失。
多层嵌套异常也能一层捕获
如果某个 thunk 内部又调用了可能出错的函数(比如读文件、网络请求、用户输入解析),这些异常仍会向上冒泡到 f() 调用点,被同一个 try-except 捕获。不需要在每个 thunk 里重复写 try ——这是蹦床结构带来的简化优势。
主动抛出异常不影响蹦床流程
你可以在任何 thunk 中用 raise 抛出自定义异常(比如 raise RuntimeError("数据校验失败")),它会被外层循环捕获,然后由你决定是终止、降级处理,还是返回默认值。这种控制权完全交还给开发者,而不是依赖语言自动展开栈。











