利用异常实现越级return(Python实现)
异常是一类消息
在面向对象的世界里,对象之间的交互表现为消息的传递。
异常也是一种消息,就我的理解,异常并非错误,它经常用来表明存在错误,但本质上它是一类特殊的消息,关联着一种跳出局部范围的机制。
It is my understanding that exceptions are not errors, and that they should only be used for exceptional conditions (e.g. I try to write a file into disk and there is no more space, or maybe I do not have permission), and not for flow control.
而在Python的世界里,所有异常都必须是BaseException的子类。
所谓异常是消息,指的是一个异常对象可以携带信息,捕获异常(就得到了一个异常对象)或者传递一个异常对象,你就可以从这个异常对象中提取信息。这个消息有时会被认为是一个指令或者信号,即便仅仅只是捕获到了一个特定类型的异常对象,例如,某个无限循环中有一个捕获异常的语句,当捕获到某个类型的异常对象时,它就认为接收到了退出的信号,快速、优雅地退出。
处理异常的语句是流程控制语句
当异常发生时,异常现场所在的局部范围就将被丢弃,并且把相关统计信息存储在一个异常对象中向上冒泡。所谓的局部范围,包括控制语句内部、局部作用域等层次结构中。
如果定义了一个关于异常的类型系统,那么就会配套实现对异常现场的信息搜集策略、异常的冒泡机制和处理异常的语句。
处理异常的语句,专门针对异常消息,会根据条件来判定,对某个异常是放行还是压下。这种流程控制,设计专门用来控制异常对局部范围的破坏。
异常是一种强化版的return
一个函数调用完成时,就会在调用它的地方返回一个值。调用完成,意味着以下3种含义之一:
- 执行完函数体中的代码,自动返回
- 遇到return语句,返回
- 抛出异常
当函数调用完成后,将会销毁调用时所临时创建的局部作用域并回收相关资源。如果函数a
在它的函数体内调用了函数b
,而b
中冒泡了一个异常,未能在a
中压下,那么就会在a
冒泡给a
的调用者。在多层次调用结构中,如果到达顶级层次依然不能被压下,那么程序将会退出。在一些解释器、虚拟机或者某些具有监控功能的执行环境中,程序因为异常退出时,将会自动记录下相关的信息,便于开发者理解问题所在。
抛出异常,未能被压下,将会不断地往上冒泡,并让局部环境不可被再次利用,程序的执行环境将自动回收这个局部环境所占用的资源。不过异常可以引用其它对象,可以被捕获,从中提取信息。正因为可以在退出函数时携带信息冒泡给函数的调用者,所以我说异常是一种强化版的return,调用者完全可以压下异常,从里面取出信息,就像是return给它的一样。
在Python中用异常实现一个越级return机制
1 | import functools |
下面文件中定义的函数,用于测试说明
leepfrog
装饰器函数的功用
1 | import functools |
测试结果如下:
1 | value = foo1() |
利用异常实现越级return(Python实现)
https://chenyanggao.github.io/2019/05/28/3.利用异常实现越级return(Python实现)/