python之捕捉异常_python捕捉异常-程序员宅基地

技术标签: 算法  python  机器学习  Python基础  人工智能  开发语言  


前言

如果异常未捕捉,系统就会一直将异常传递下去,直到程序由于异常而异常而中断。为了避免出现这种程序异常中断的情况,现在对“危险”的代码段进行异常捕捉。在python语言中,使用try……except语句进行异常捕获。那么这个语句有哪些用法呢?


一、try……except语句的基本用法

try……except语句用于捕获代码块中的异常。在使用try……except语句之前,先看一下不使用该语句的情况。

x = int(input('请输入分子:'))
y = int(input('请输入分母:'))
print('x/y={}'.format(x / y))

执行上面的代码后,分子输入任意的数值,分母输入0,会抛出,会抛出下述所示的异常,从而导致程序奔溃,也就是说,本来正常执行第3条语句(print函数),但由于x/y中的y变量是0,所以直接抛出了异常,因此,第三条语句后面所有的语句都不会被执行。

请输入分子:>? 30
请输入分母:>? 0
Traceback (most recent call last):
  File "D:\ProgramData\Anaconda3\lib\site-packages\IPython\core\interactiveshell.py", line 2963, in run_code
    exec(code_obj, self.user_global_ns, self.user_ns)
  File "<ipython-input-2-ece946d564d3>", line 3, in <module>
    print('x/y={}'.format(x / y))
ZeroDivisionError: division by zero

由于用户的输入是不可控的,所以当采集用户输入的数据时,应该使用try……except语句对相关代码进行异常捕捉,尽管异常并不会每次都发生,但这么做可以有备无患。

1、本例通过try……except语句捕捉用户输入可能造成的异常,如果用户输入了异常数据,会提示用户,并要求重新输入数据
x = None
while True:
    try:
        # 如果x已经有了值,表示已经捕捉了异常,那么再次输入数据时,就不需要输入x值了
        if x == None:
            x = int(input('请输出分子:'))
        y = int(input('请输入分母:'))
        print('x/y={}'.format(x / y))
        break
    except:
        print('分母不能为0,请重新输入分母')  # 只有发生异常时,才会执行这行代码

执行上面的代码,分子输入30,分母输入0,按enter键会输出异常提示信息,然后会要求再次输入分母,输入一个非零的数值,如30,按enter键后,会输出x/y的结果。

请输出分子:>? 30
请输入分母:>? 0
分母不能为0,请重新输入分母
请输入分母:>? 30
x/y=1.0

从上面的例子可以了解关于try……except语句的如下几方面内容:

  1. try……except语句是一个代码块,所以try和except后面都要加冒号(:)
  2. try和except之间是正常执行的语句,如果这些代码不发生错误,那么就会正常执行下去,这时except部分的代码时不会执行的。如果try 和except之间的代码发生了错误,那么错误点后面的代码都不会被执行了,而会跳到except子句去执行except代码块中的代码。
  3. 如果except关键字后面没有指定任何异常类,那么except部分可以捕捉任何的异常。

二、捕捉多个异常

我们并不能预估一个代码块到底会不会抛出异常,以及抛出多少中异常。所以需要使用try……except语句捕捉尽可能多的异常,因此,except子句可以包含任意多个。不过程序员并不能准确估计一代码块抛出的异常种类,所以使用具体异常类来捕捉异常,有可能会遗漏某个异常,在这种情况下,当抛出这个当抛出这个被遗漏的异常后,程序还是会崩溃,所以比较保险的做法是最后一个except子句不使用任何异常类,这样就会捕捉其他所有未指定的异常没从而让程序更加健壮。

try:except 异常类1:
	…
except 异常类2:
	…
	…
except 异常类n:
	…
except#捕捉其他未指定的异常
  1. 本例将通过SpecialCale类的三个方法(add、sub、mul)和raise语句抛出两个自定义的异常(NegativeException和ZeroException),div方法可能会派出内建的NegativeException异常。这位三个会通过except子句进行捕捉,最后会使用except语句捕捉其他未指定的异常。本例的很逻辑在while循环中,通过console输入表达式(如add),动态调用SpecialCale类的相应方法,不管是抛出异常还是正常掉调用,都会重新要求输入新的表达式,直到输入“end”命令退出while 循环。
# 自定义异常类,表示操作数或计算结果为负数时抛出异常
class NegativeException(Exception):
    pass


# 自定义异常类,表示操作数为0时抛出的异常
class ZeroException(Exception):
    pass


class SpecialCalc:
    def add(self, x, y):

        # 当x和y有一个小于0时抛出NegativeException异常
        if x < 0 or y < 0:
            raise NegativeException
        return x + y

    def sub(self, x, y):

        # 当x-y的差值是负数时或抛出NegativeException异常
        if x - y < 0:
            raise NegativeException
        return x - y

    def mul(self, x, y):

        # 当x和y至少有一个是0是抛出ZeroException异常
        if x == 0 or y == 0:
            raise ZeroException
        return x * y

    def div(self, x, y):
        return x / y


while True:
    try:
        # 创建SpecialCalc实例
        calc = SpecialCalc()
        # 从console输入表达式
        expr = input("请输入要计算的表达式,例如add(1,2):")
        if expr == 'exit':
            break
        # 使用eval函数动态执行输入的表达式,前面需要加上‘calc.’前缀
        # 因为这些方法都属于SpecialCalc类
        result = eval('calc.' + expr)
        # 在控制台输出结果,保留小数点后两位
        print('计算结果:{:.2f}'.format(result))
    except NegativeException:
        print('********负数异常******')
    except ZeroException:
        print('******操作数为0异常****')
    except ZeroDivisionError:
        print('******分母不能为0******')
    except:
        print('****其他异常**********')

运行上面的程序,并输入不同的表达式来引发两个定制的异常和ZeroDivsionError,以及输入错误的表达式以便引发其他异常,运行结果如下:

请输入要计算的表达式,例如add(1,2):add(1,3)
计算结果:4.00
请输入要计算的表达式,例如add(1,2):add(-5,3)
********负数异常******
请输入要计算的表达式,例如add(1,2):sub(4,6)
********负数异常******
请输入要计算的表达式,例如add(1,2):div(40,0)
******分母不能为0******
请输入要计算的表达式,例如add(1,2):div(53,21)
计算结果:2.52
请输入要计算的表达式,例如add(1,2):abvcd
****其他异常**********
请输入要计算的表达式,例如add(1,2):exit

Process finished with exit code 0

插曲:在调试上面的代码的时候由于自己的粗心,中间一个标点符号打错了,然后持续运行之后出现这样的情况。

请输入要计算的表达式,例如add(1,2):add(1,2)
****其他异常**********
请输入要计算的表达式,例如add(1,2):sub(4,2)
****其他异常**********
请输入要计算的表达式,例如add(1,2):div(5,2)
****其他异常**********
请输入要计算的表达式,例如add(1,2):exit

Process finished with exit code 0

直到我祛除了最后一行捕捉其他异常的错误信息之后再次进行调试,才发现了问题在哪。

请输入要计算的表达式,例如add(1,2):add(1,3)
Traceback (most recent call last):
  File "D:/pyproject/leetcode/editor/LeetCode学习.py", line 66, in <module>
    print('计算结果:{:.2f}'.format(result))
KeyError: ':'

Process finished with exit code 1

从上面的错误信息中能够看到错误的代码以及代码所在的行数等,是我在格式化输出的时候没有冒号错误使用了中文的冒号。所以,在捕捉异常的时候,如果代码出现了其他异常,注释掉最后一个捕捉所有异常的代码,再次运行也许是一个不错的选择。


三、用同一个代码块处理多个异常

虽然代码块可能抛出多个异常牡丹石有时多个异常的处理程序可以是一个,在这种情况下,如果用多个except子句捕捉这些异常,就需要在每一个except子句中使用同一段代码处理这些异常。为了解决这个问题,except子句允许指定多个异常,这样指定后,同一个except子句就可以捕捉多个异常了。

try:
	……
except(异常1,异常2,异常3,……异常n)
  1. 本例定义了一个raiseException函数,用于随机抛出三个自定义异常,然后用同一个except子句捕捉异常。
# 第一个自定义异常类
class CustomException1(Exception):
    pass


# 第二个自定义异常类
class CustomException2(Exception):
    pass


# 第二个自定义异常类
class CustomException3(Exception):
    pass
#导入random模块
import random
#随机抛出前三个自定义异常
def raiseExecption():
    n=random.randint(1,3)
    print('抛出CustomException{}异常'.format(n))
    if n==1:
        raise CustomException1
    elif n==2:
        raise CustomException2
    else:
        raise CustomException3

try:
    raiseExecption()
#使用except子句同时捕捉这三个异常
except(CustomException1,CustomException2,CustomException3):
    print('*****执行异常处理结果******')

运行结果如下:

第一次运行结果:
抛出CustomException2异常
*****执行异常处理结果******

第二次运行结果:
抛出CustomException3异常
*****执行异常处理结果******



总结

以上就是本文要介绍大的主要内容,在前面一篇文章中主要介绍了什么是异常,如何创建异常类以及如何主动抛出异常,本文则重点介绍如何捕捉异常,try……except语句的基本用法、以及如何捕捉多个异常等

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/sdqqz/article/details/126062841

智能推荐

微信小程序源码案例大全_微信小程序switch页面demo-程序员宅基地

文章浏览阅读4.3k次,点赞4次,收藏62次。微信小程序demo:足球,赛事分析 小程序简易导航 小程序demo:办公审批 小程序Demo:电魔方 小程序demo:借阅伴侣 微信小程序demo:投票 微信小程序demo:健康生活 小程序demo:文章列表demo 微商城(含微信小程序)完整源码+配置指南 微信小程序Demo:一个简单的工作系统 微信小程序Demo:用于聚会的小程序 微信小程序Demo:Growth 是一款..._微信小程序switch页面demo

SLAM学习笔记(Code2)----刚体运动、Eigen库_eigen.determinant-程序员宅基地

文章浏览阅读2.2k次。2.1除了#include<iostream>之外的头文件#include <Eigen/Core>//Core:核心#include <Eigen/Dense>//求矩阵的逆、特征值、行列式等#include <Eigen/Geometry>//Eigen的几何模块,可以利用矩阵完成如旋转、平移/***其他***/#include <ctime>//可用于计时,比较哪个程序更快#include <cmath>//包含a_eigen.determinant

图像梯度-sobel算子-程序员宅基地

文章浏览阅读1w次,点赞12次,收藏61次。(1)理论部分x 水平方向的梯度, 其实也就是右边 - 左边,有的权重为1,有的为2 。若是计算出来的值很大 说明是一个边界 。y 竖直方向的梯度,其实也就是下面减上面,权重1,或2 。若是计算出来的值很大 说明是一个边界 。图像的梯度为:有时简化为:即:(2)程序部分函数:Sobelddepth 通常取 -1,但是会导致结果溢出,检测不出边缘,故使..._sobel算子

cuda10.1和cudnn7.6.5百度网盘下载链接(Linux版)_cudnn7.6网盘下载-程序员宅基地

文章浏览阅读3.6k次,点赞17次,收藏8次。cuda10.1和cudnn7.6.5百度网盘下载链接(Linux版)在官网下载不仅慢,,,主要是还总失败。。终于下载成功了,这里给出百度网盘下载链接,希望可以帮到别人百度网盘下载链接提取码: vyg5_cudnn7.6网盘下载

Python正则表达式大全-程序员宅基地

文章浏览阅读9.3w次,点赞69次,收藏427次。定义:正则表达式是对字符串(包括普通字符(例如,a 到 z 之间的字母)和特殊字符(称为“元字符”))操作的一种逻辑公式,就是用事先定义好的一些特定字符、及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑。正则表达式是一种文本模式,该模式描述在搜索文本时要匹配的一个或多个字符串。上面都是官方的说明,我自己的理解是(仅供参考):通过事先规定好一些特殊字符的匹配规则,然后利用这些字符进行组合来匹配各种复杂的字符串场景。比如现在的爬虫和数据分析,字符串校验等等都需要用_python正则表达式

Vue之条件渲染_条件渲染的基本概念-程序员宅基地

文章浏览阅读973次。条件渲染就是在指定的条件下,渲染出指定的UI。比如当我们显示主页的时候,应该隐藏掉登录等一系列不相干的UI元素。即UI元素只在特定条件下进行显示。而在VUE3中,这种UI元素的显示和隐藏可以通过两个关键字,`v-if` 和`v-show`来实现。但是虽然实现的功能一样,但他们两者有着一些细微的区别。总结起来这个区别就是:v-show控制UI元素隐藏时只是将UI的显示状态变成了不可见,实际上这个UI是存在的,但是v-if隐藏UI元素时则是直接干掉了这个UI元素,使其不显示_条件渲染的基本概念

随便推点

NILM(非侵入式电力负荷监测)学习笔记 —— 准备工作(一)配置环境NILMTK Toolkit_nilmtk学习-程序员宅基地

文章浏览阅读1.9w次,点赞27次,收藏122次。安装Anaconda,Python,pycharm我另一篇文章里面有介绍https://blog.csdn.net/wwb1990/article/details/103883775安装NILMTK有了上面的环境,接下来进入正题。NILMTK官网:http://nilmtk.github.io/因为官方安装流程是基于linux的(官方安装流程),我这里提供windows..._nilmtk学习

k8s-pod 控制器-程序员宅基地

文章浏览阅读826次,点赞20次,收藏28次。如果实际 Pod 数量比指定的多那就结束掉多余的,如果实际数量比指定的少就新启动一些Pod,当 Pod 失败、被删除或者挂掉后,RC 都会去自动创建新的 Pod 来保证副本数量,所以即使只有一个 Pod,我们也应该使用 RC 来管理我们的 Pod。label 与 selector 配合,可以实现对象的“关联”,“Pod 控制器” 与 Pod 是相关联的 —— “Pod 控制器”依赖于 Pod,可以给 Pod 设置 label,然后给“控制器”设置对应的 selector,这就实现了对象的关联。

相关工具设置-程序员宅基地

文章浏览阅读57次。1. ultraEdit设置禁止自动更新: 菜单栏:高级->配置->应用程序布局->其他 取消勾选“自动检查更新”2.xshell 传输文件中设置编码,防止乱码: 文件 -- 属性 -- 选项 -- 连接 -- 使用UTF-8编码3.乱码修改:修改tomcat下配置中,修改: <Connector connectionTimeou..._高级-配置-应用程序布局

ico引入方法_arco的ico怎么导入-程序员宅基地

文章浏览阅读1.2k次。打开下面的网站后,挑选要使用的,https://icomoon.io/app/#/select/image下载后 解压 ,先把fonts里面的文件复制到项目fonts文件夹中去,然后打开其中的style.css文件找到类似下面的代码@font-face {font-family: ‘icomoon’;src: url(’…/fonts/icomoon.eot?r069d6’);s..._arco的ico怎么导入

Microsoft Visual Studio 2010(VS2010)正式版 CDKEY_visual_studio_2010_professional key-程序员宅基地

文章浏览阅读1.9k次。Microsoft Visual Studio 2010(VS2010)正式版 CDKEY / SN:YCFHQ-9DWCY-DKV88-T2TMH-G7BHP企业版、旗舰版都适用推荐直接下载电驴资源的vs旗舰版然后安装,好用方便且省时!) MSDN VS2010 Ultimate 简体中文正式旗舰版破解版下载(附序列号) visual studio 2010正_visual_studio_2010_professional key

互联网医疗的定义及架构-程序员宅基地

文章浏览阅读3.2k次,点赞2次,收藏17次。导读:互联网医疗是指综合利用大数据、云计算等信息技术使得传统医疗产业与互联网、物联网、人工智能等技术应用紧密集合,形成诊前咨询、诊中诊疗、诊后康复保健、慢性病管理、健康预防等大健康生态深度..._线上医疗的定义

推荐文章

热门文章

相关标签