好多时候,都忘记自己还是个技术博主了
可以直接看结论
有福利
什么是异常捕捉
异常捕捉是指在程序运行过程中,遇到异常情况时,通过捕获异常并处理异常,使程序能够继续运行,而不是崩溃。这是现代编程语言里面的一个重要的概念。
例如在Python里面,我们可以使用try…except语句来捕捉异常。
def division(a,b):try:# 可能会抛出异常的代码return a/bexcept ZeroDivisionError:# 处理异常的代码print("除数不能为0")return None
像上面这个函数,我们可以捕捉除数为0的异常。如果没有这个函数,那么这个功能放到整个流程里面,就有可能出现程序中断,如下所示:
可以看见,如果不用异常捕捉程序在运行到运算的时候,出现了异常,导致程序崩溃,后面的流程就执行不下去了。
而用了异常捕捉,程序在运行到运算的时候,出现了异常,但是我们捕捉到了异常,所以程序没有崩溃,后面的流程继续执行。
这里我们用了一个ZeroDivisionError异常,来捕捉除数为0的异常。以此类推,还可以加上其他的异常,例如类型异常TypeError:
def division(a,b):try:# 可能会抛出异常的代码return a/bexcept ZeroDivisionError:# 处理异常的代码print("除数不能为0")return Noneexcept TypeError:# 处理异常的代码print("类型错误")return Noneexcept:# 处理异常的代码print("其他异常")return None
当然,我们不可能列举所有的异常,所以我们可以使用一个通用的异常捕捉,来捕捉所有的异常。
异常捕捉的应用与性能案例
所以,有些写算法的同学,为了方便,会脑洞大开的利用异常来进行逻辑判定,例如判定你输入的是不是数字,就会这样写算法:
def isNumeric(val):try:val + 1return Trueexcept TypeError:return False
(别笑……这是ArcGIS的官方源码……)
实际上算法是可以成功运行的(效果还不错),如下所示:
而Python官方对于数值的判定,建议使用的isinstance()或者说type()函数,如下所示:
def isNumeric2(val):return isinstance(val, (int, float, complex))def isNumeric3(val):return type(val) == int or type(val) == float or type(val) == complex
运行结果如下:
在功能一样的情况下,我们来测试一下这几个函数的运行效率,首先是结果True的情况:
![[虾神说算法] 若为性能计,非必要,少用异常捕捉](https://www.fanshouji.com/wp-content/uploads/2025/10/284999.png)
我们发现,如果结果是True,用数学运算的效率是最高的,因为不他走异常捕捉,而且也不走逻辑判断,加法运算是可以直接走CPU的。
其次是type,最后是isinstance的性能。
然后我们来进行false测试:
我们可以看见,不管是type还是isinstance,在结果是False的情况下,性能要远远高于走try...except的异常捕捉。
这里,从异常捕捉的原理来看,异常发生并进入 except 处理时,会产生明显性能开销,其原因包括:
-
生成异常对象(如 ValueError 实例),需保存异常追踪信息(调用栈、错误位置等); -
遍历 except 块列表匹配异常类型; -
中断正常执行流程,切换到异常处理上下文。
结论:
-
在对问题可以预见的情况下,不建议用 try-except 替代常规条件判断:如判断字符串是否可转整数,应优先用 str.isdigit() 而非依赖 try int(s) except ValueError(后者在高频调用场景会导致性能瓶颈)。
所以,对于第一个除法代码函数的应用,如果要追求最好性能的话,我们可以在一些可以预期错误的问题上,用isinstance()或者type()函数来替代异常捕捉。
代码如下:
def division(a,b):try:if not isinstance(a, (int, float, complex)) or not isinstance(b, (int, float, complex)):print("非数值无法进行除法运算")return Noneelif b == 0:print("除数不能为0")return None# 可能会抛出异常的代码return a/bexcept Exception as ex:# 处理异常的代码print("其他异常", ex)return None
在数学运算上,绝大部分异常就是这两列,但是你也不敢保证所有的异常都在这两列,所以最后还是要追加一个except,反正一些特殊的意外。
-
对于很多无法预计的问题,适合处理 “意外异常”:如网络请求超时、文件突然被删除等低概率异常,此时性能消耗可接受,且代码更简洁。
打完收工。
我是福利