Python - 异常处理

 前言

运行中的程序不知道怎么搞的报错了,恰好没有处理这个报错,程序也随之终止了,有没有什么办法能够让程序报错也能够不崩掉继续运行呢?答案是有的,就是通过异常处理。

什么是异常

异常顾名思义就是不正常,是程序发出错误的信号,程序一旦出现错误,就会产生异常,如果没有处理该异常的话,程序就会随之终止。比如以下程序抛出异常:

>>> x
Traceback (most recent call last):  # Traceback:追踪回溯异常File "<stdin>", line 1, in <module>  # 定位异常的位置
NameError: name 'x' is not defined  # NameError:异常的类型

异常大致分为两种情况:

一种是语法错误SyntaxError,语法错误在程序运行前就应该修改,属于低级错误~

>>> ifFile "<stdin>", line 1if^
SyntaxError: invalid syntax

另一种是逻辑上的错误,比如TypeError、NameError、IdenxError

# TypeError:数字类型与字符串类型不能进行计算
1 + ’2’# ValueError:类型转换的错误
num = input(">>: ")  # 比如输入的是'python'
int(num)# NameError:引用了一个不存在的名字x
x# IndexError:索引超出列表的限制
list1 = ['python','java']
l[3]# KeyError:引用了一个不存在的key
dic={'name':'python'}
dic['age']# AttributeError:对象属性不存在
class Test:pass
Foo.x

如何进行异常处理

为了增强程序的健壮性,即便是程序运行过程中出错了,也不要终止程序。而是捕捉异常并处理:将出错信息记录到日志内。

语法错误

语法上出现的错误必须在程序运行前更正。

if True  #  SyntaxError: invalid syntaxprint('if分支没有加:')

逻辑上的错误

逻辑上的错误分为两种情况,一种是错误的条件可以预知,另一种就是发生错误的条件无法预知。

可以预知发生错的误条件

如果错误的条件可以预知,可以通过if判断解决,比如:

age = 18
inp_age = input('>>').strip()
# 可以预知字符串与数字无法进行大小的比较
if inp_age.isdigit():inp_age = int(inp_age)if age > inp_age:print('bigger')else:print('error')
else:print('请输入数字')

无法预知发生错误的条件

在无法预知发生错误的条件的情况下,保证程序的可靠性,使程序不会崩溃终止,就需要对异常进行处理,异常处理的基本形式如下:

try:需要检查是否会出现异常的代码
except 异常类型 as e:  # as将异常的类型赋值给变量e,打印e可以知道错误的具体原因如果代码检测出现异常,就执行这里的代码

如下出现异常的代码,可以使用异常处理进行处理:

try:print('异常检查开始')print(name)print('异常检查结束')
except NameError as e: print(f'出现异常了{e}')
print('程序没有终止,其他代码继续执行')# 上述代码执行结果
异常检查开始
出现异常了name 'name' is not defined
程序没有终止,其他代码继续执行

如果被检查的代码块中有可能出现不同类型的异常时,针对不同类型的异常如果想分别用不同的逻辑处理可以使用多个分支的except,类似于多分支的elif,语法如下:

try:需要检查是否会出现异常的代码
except NameError:检测到NameError时执行的代码
except KeyError:检测到KeyError时执行的代码
except ......

比如下述代码:

def transfer_int(info):try:res = int(info)except ValueErro as e:print(f'valueerror {e}')res = 'valueerror'except TypeError as e:print(f'typeerror {e})res = typeerrorreturn restransfer_info('python')  # ValueError: invalid literal for int() with base 10: 'python'
transfer_int({'x': 1})  # TypeError: int() argument must be a string, a bytes-like object or a number, not 'dict'

如果多种异常想用同一种逻辑进行处理,可以将多种异常放入元组中,用一个except分支进行处理。

try:需要检查是否会出现异常的代码
except (NameError, ValueError, IndexError):代码中出现元组中三种异常时执行这里的代码

有小伙伴有疑问了,难道我需要把程序运行中可能出现的异常都需要写一遍了,也太麻烦了吧。为了方便开发人员处理异常,python提供了一种万能异常类型Exception,可以捕获所有的异常:

try:需要检查是否会出现异常的代码
except (NameError, ValueError, IndexError):代码中出现元组中三种异常时执行这里的代码
except Exception:出现其他类型异常统一使用这里的逻辑

比如下述代码:

print('start...')try:print('1111111111')l = ['aaa', 'bbbb']l[3] # 抛出异常IndexError,该行代码同级别的后续代码不会运行print('2222222222')xxxprint('33333333')dic = {'a': 1}dic['aaa']
# except (IndexError, NameError) as e:
#     print('异常的信息: ', e)
# except KeyError as e:
#     print('字典的key不存在: ', e)
except Exception as e:  # 万能异常print('所有异常都可以匹配的到')
print('end....')

使用异常处理时后面还可以跟一个else,但是else必须跟在except之后,不能但粗存在,当需要检查的代码没有触发任何异常的情况下就会执行else下的代码块。

try:print('1111111111')l = ['1',2]print('2222222222222')print(33333333333)
except IndexError as e:  # 不执行这里的代码块,else才会执行print('异常信息',e)# 只有再try内代码没有异常才会执行else
else:print('我是else')

此外,try还可以与finally使用,从语法上说finally必须放在else之后,但是可以使用try-except-finaally的语法格式,也可以直接使用try-finally的格式,无论被检测的代码是否出现异常,finally后的代码都会正常执行,因此finally的代码块中可以做一些系统资源回收的操作,比如打开的文件。

print('start...')try:print('1111111111')l = ['aaa', 'bbbb']l[3] # 抛出异常IndexError,该行代码同级别的后续代码不会运行print('2222222222')xxxprint('33333333')dic = {'a': 1}dic['aaa']f = open(r'a.txt', 'r', encoding='utf-8')
finally: # 不处理异常,无论是否发生异常都会执行finally的子代码print('====》》》》》应该把被检测代码中回收系统资源的代码放到这里')if f:f.close()print('end....')

raise - 手动触发异常

对于不符合python解释器的语法或者逻辑的代码,在运行时,python解释器会主动抛出异常,如果在程序运行中,出现了违反了开发人员自定义的各种逻辑或者规则,开发人员也可以自己明确的触发异常,可以使用raise关键字手动触发异常,raise后面必须是一个异常的类或者异常的实力。

class Info():def __init__(self, name):if type(name) is not str:raise TypeError('name must be str')self.name = namei = Info(123)  #  # TypeError: name must be str

异常处理的使用场景

为了提高程序的健壮性,很多刚入门编程的小伙伴认为应该为程序尽可能的多加try...except,这是一种过度使用异常处理的方式,是不正确的 ,对于可以预知可能会触发异常的条件,建议使用if分支进行判断;而对于一些无法预知的、有很大几率会触发异常的条件才进行异常处理,比如下载时网络出现问题,这种情况无法预知只能使用异常处理。

最后感谢每一个认真阅读我文章的人,礼尚往来总是要有的,这些资料,对于【软件测试】的朋友来说应该是最全面最完整的备战仓库,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走:

这些资料,对于【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴上万个测试工程师们走过最艰难的路程,希望也能帮助到你! 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/638233.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

记一次多平台免杀PHP木马的制作过程

注意&#xff1a;本文转载自本作者稀土掘金博客 博客地址&#xff1a; 御坂19008号 的个人主页 - 动态 - 掘金 文章目录 前言声明绕过情况使用方法运行环境绕过点介绍技术原理讲解变量传值覆盖模块代码执行阻断模块InazumaPuzzle程序锁定器PerlinNoise危险函数生成与执行类构造…

基于springboot+vue考编论坛

摘要 近年来&#xff0c;随着互联网的迅猛发展&#xff0c;编程论坛成为程序员们交流学术、分享经验的重要平台之一。为了满足广大程序员的需求&#xff0c;本文基于Spring Boot和Vue框架&#xff0c;设计并实现了一个功能强大的编程论坛。首先&#xff0c;我们选择Spring Boot…

Laya3.0 相机使用

摄像机&#xff0c;是3D场景里边最经常使用的对象了。 官方文档&#xff1a;点击这里学习 1.投影 Projection 透视&#xff1a; 模拟人眼的视觉效果&#xff0c;近大远小。模拟物理世界的规律&#xff0c;将眼睛或相机抽象成一个点&#xff0c;此时视锥体内的物体投影到视平…

ChatGPT时代对大数据应用的展望

前言&#xff1a; 2022年底&#xff0c;科技圈有个爆炸性新闻&#xff0c;ChatGPT的诞生&#xff0c;引发了世界范围内的震惊&#xff1b;人工智能在与人交流上有了划时代的技术突破&#xff0c;可以和人深入的理解交流&#xff0c;让许多公司和领域对这项技术有了更多遐想。对…

开源项目盘点-学习类

1&#xff0c;freeCodeCamp 地址&#xff1a;https://github.com/freeCodeCamp/freeCodeCamp 描述&#xff1a;一个程序员学习网站&#xff0c;里面有全栈开发、机器学习的相关知识&#xff0c;是完全免费的&#xff0c;该网站有上千道编码挑战题来帮助你来练习你的技能。 提…

AI对比:ChatGPT与文心一言的异同与未来

文章目录 &#x1f4d1;前言一、ChatGPT和文心一言概述1.1 ChatGPT1.2 文心一言 二、ChatGPT和文心一言比较2.1 训练数据与知识储备2.2 语义理解与生成能力2.2 应用场景与商业化探索 三、未来展望3.1 模型规模与参数数量不断增加3.2 多模态交互成为主流3.3 知识图谱与大模型的结…

大数据平台的硬件规划、网络调优、架构设计、节点规划

1.大数据平台硬件选型 要对Hadoop大数据平台进行硬件选型,首先需要了解Hadoop的运行架构以及每个角色的功能。在一个典型的Hadoop架构中,通常有5个角色,分别是NameNode、Standby NameNode、ResourceManager、NodeManager、DataNode以及外围机。 其中 NameNode 负责协调集群…

【51单片机】

0、前言 参考&#xff1a;普中 51 单片机开发攻略 第14章 1、硬件 ULN2003 芯片 2、软件 mian.c #include <reg52.h> #include <intrins.h> #include "delayms.h"typedef unsigned char u8; typedef unsigned int u16;sbit DC_MotorP1^0;void DC_Mo…

Ubuntu 使用 git 能够 clone 但不能 push 的参考解决方法

写在前面 自己的测试环境&#xff1a;Ubuntu20.04 下面的操作都是和 git 有关&#xff0c;所以针对不同的操作系统&#xff08;比如 Windows&#xff09;也是一样的。 一、问题描述 在此之前使用git执行 git push origin master 的命令时&#xff0c;能够正常执行&#xff0…

【计算机网络】【Python】【练习题】【新加坡南洋理工大学】【Computer Control Network】

一、题目描述 该题目描述一个网络中数据包交换&#xff08;Packet Switching&#xff09;的例子。题目如下&#xff1a; 二、问题解答&#xff08;使用Python&#xff09; Q1&#xff1a;如何求出0.0004这个值&#xff1f; &#xff08;1&#xff09;、公式推导过程&#xf…

数据库防水坝是什么?有什么作用?有哪些优势?

数据库是公司重要IT资产&#xff0c;是公司数据存储、数据整合、数据备份等重要载体。所以保障数据库安全至关重要。目前保障数据库安全产品较多&#xff0c;例如堡垒机、防火墙、数据库防水坝等等。今天我们就先来简单了解一下数据库防水坝是什么&#xff1f;有什么作用&#…

CMU15-445-Spring-2023-分布式DBMS初探(lec21-24)

Lecture #21_ Introduction to Distributed Databases Distributed DBMSs 分布式 DBMS 将单个逻辑数据库划分为多个物理资源。应用程序&#xff08;通常&#xff09;并不知道数据被分割在不同的硬件上。系统依靠单节点 DBMS 的技术和算法来支持分布式环境中的事务处理和查询执…

DAG最小路径点覆盖,最小路径可重复覆盖,详解

文章目录 前言有向无环图的最小路径点覆盖概念拆点二分图定理**证明** 最小路径可重复覆盖解决策略代码实现 OJ练习 前言 关于二分图&#xff1a;二分图及染色法判定 关于二分图最大匹配&#xff1a;二分图最大匹配——匈牙利算法详解 关于二分图带权最大完备匹配&#xff1…

k8s节点RouteCreated为false

出现该情况后&#xff0c;一般是初始化节点失败。因此&#xff0c;需要把节点从集群中移除&#xff0c;再加入到集群中&#xff0c;即可解决。 通常出现这个状况后&#xff0c;该节点上是没有被分配pod ip的&#xff0c;可以通过命令查看&#xff1a; # 发现没有PodCIDR、PodC…

【flutter】完全自定义样式模态对话框

示例完成结果展示&#xff1a; 示例组件代码&#xff1a; context&#xff1a;上下文 title&#xff1a;提示标题&#xff0c;null时不显示 content&#xff1a;提示内容&#xff0c;null时不显示 cancelText&#xff1a;取消按钮文字&#xff0c;null时不显示取消按钮 confirm…

GPT应用_PrivateGPT

项目地址&#xff1a;https://github.com/imartinez/privateGPT 1 功能 1.1 整体功能&#xff0c;想解决什么问题 搭建完整的 RAG 系统&#xff0c;与 FastGPT 相比&#xff0c;界面比较简单。但是底层支持比较丰富&#xff0c;可用于知识库的完全本地部署&#xff0c;包含大…

2024年【金属非金属矿山(地下矿山)安全管理人员】证考试及金属非金属矿山(地下矿山)安全管理人员模拟考试题库

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2024年【金属非金属矿山&#xff08;地下矿山&#xff09;安全管理人员】证考试及金属非金属矿山&#xff08;地下矿山&#xff09;安全管理人员模拟考试题库&#xff0c;包含金属非金属矿山&#xff08;地下矿山&…

基于 IDEA 创建 Maven 工程

1. 概念梳理Maven工程的GAVP Maven工程相对之前的项目&#xff0c;多出一组gavp属性&#xff0c;gav&#xff08;表示当前工程的坐标&#xff09;需要我们在创建项目的时候指定&#xff0c;p&#xff08;表示打包方式&#xff09;有默认值&#xff08;默认为 jar 包&#xff0…

STM32标准库开发—SPI通信介绍

SPI通信 硬件电路 注意&#xff1a;为避免输入信号&#xff08;MISO&#xff09;造成冲突&#xff0c;只有被SS选中的设备才能使用MISO进行通信&#xff0c;空闲状态下该引脚呈现高阻态模式 SPI信号移位示意图 主机与从机通过交换时序实现数据传输&#xff0c;无论要与不要都需…

python文件操作的基本流程

引入 程序运行过程中产生的数据会保存到内存中&#xff0c;如果想要永久保存下来&#xff0c;就必须将数据存放在硬盘上&#xff0c;应用程序如果想要操作计算机的硬件就必须通过操作系统&#xff0c;文件就是操作系统提供给应用程序来操作硬盘的虚拟概念&#xff0c;应用程序…