Python基础之异常处理

程序在运行过程中,难免会遇到错误,有的是编写人员疏忽造成的语法错误,有的是程序内部隐含逻辑问题造成的数据错误,还有的是程序运行时与系统的规则冲突造成的系统错误,等等。如果出错就不会执行出错语句后面的代码,导致程序异常中断,因此为了提高程序健壮性,容错性,对容易发生错误的语句需要捕获异常对异常处理,保证程序的连续性提高稳定性。

def get_num(l:list, n1:int, n2:int):print('执行get_num函数')num1 = l[n1]num2 = l[n2]res = num1/num2return resdef func_1():print('执行func_1函数')def func_2():print('执行func_2函数')get_num([1,2,3,4],5)
func_1()
func_2()

上述代码在调用函数get_num时会抛出indexError的异常,导致程序中断 

def func_1():x = 10y = 0b = x/yprint(b)print("做完除法后需要执行的代码")Traceback (most recent call last):File "/Users/fujinjie/PythonProjects/develop_test/buyer_app_autotest/unit_test.py", line 30, in <module>r = func_1()File "/Users/fujinjie/PythonProjects/develop_test/buyer_app_autotest/unit_test.py", line 26, in func_1b = x/y
ZeroDivisionError: division by zero

由于y = 0 ,即除数为0,程序抛出:ZeroDivisionError: division by zero 的异常,b = x/y后面的代码并没有被继续执行,因为出错后程序是并不知道如何处理所以直接中断后续,并抛出错误告知用户,假设在我们自动化测试中,可能要执数百条用例,如果某一句子代码执行出现异常,则自动化程序就会异常中断无法继续执行测试。

当一个程序发生异常时,代表该程序在执行时出现了非正常的情况,无法再执行下去。默认情况下,程序是要终止的。如果要避免程序退出,可以使用捕获异常的方式获取这个异常的名称,再通过其他的逻辑代码让程序继续运行,这种根据异常做出的逻辑处理叫作异常处理。异常处理不仅仅能够管理正常的流程运行,还能够在程序出错时对程序进行必要的处理。大大提高了程序的健壮性和人机交互的友好性。

一、try...except...异常处理机制

def func_1():x = 10y = 0try:b = x/yprint(b)except:  # except捕获所有类型的异常,即只要有异常就捕获,不区分异常类型print("出现错误异常后,执行这里")print("做完除法后需要执行的代码")#出现错误异常后,执行这里做完除法后需要执行的代码

上面是通过try...except 优化后的函数,把会出错的代码放入try: 语句下作为try的子句,当try下面的代码出错时,程序会执行except:下面的代码,并执行程序后续代码,如果try: 下面的代码没有出错,则跳过except: 直接执行后续代码,程序继续运行。

在这里通过except我们捕获try代码块中的错误和异常,相当于告诉程序,当try下面语句出错时,该如何处理,上面我们直接做了一个字符串的输出: "出现错误异常后,执行这里"

二、except + 异常类型 捕获指定类型的异常

def func_1():x = 10y = 0try:b = x/yprint(b)except ZeroDivisionError as e:  # as 为别名,当一个变量名称太长时可取别名代替简化print(f"出错啦,错误信息:{e}")print("做完除法后需要执行的代码")出错啦,错误信息:division by zero
做完除法后需要执行的代码

基本语法构成

try:可能产生异常的代码块
except [ (Error1, Error2, ... ) [as e] ]:处理异常的代码块1
except [ (Error3, Error4, ... ) [as e] ]:处理异常的代码块2
except [Exception]:处理其它异常

该格式中,[] 括起来的部分可以使用,也可以省略。其中各部分的含义如下:

  • (Error1, Error2,...) 、(Error3, Error4,...):其中,Error1、Error2、Error3 和 Error4 都是具体的异常类型。显然,一个 except 块可以同时处理多种异常。
  • [as e]:作为可选参数,表示给异常类型起一个别名 e,这样做的好处是方便在 except 块中调用异常类型(后续会用到)。
  • [Exception]:作为可选参数,可以代指程序可能发生的所有异常情况,其通常用在最后一个 except 块。

try except 语句的执行流程如下:

  1. 首先执行 try 中的代码块,如果执行过程中出现异常,系统会自动生成一个异常类型,并将该异常提交给 Python 解释器,此过程称为。

    捕获异常

  2. 当 Python 解释器收到异常对象时,会寻找能处理该异常对象的 except 块,如果找到合适的 except 块,则把该异常对象交给该 except 块处理,这个过程被称为处理异常。如果 Python 解释器找不到处理异常的 except 块,则程序运行终止,Python 解释器也将退出。

很多时间我们并不知道try下面包裹的子句会出现何种类型的异常,对于这种情况我们一般交给 Exception来处理,即表示可以接收任何类型的异常

 

try:#...
except Exception:#...

一个简的例子

try:num_1 = int(input("输入一个整数:"))num_2 = int(input("输入另一个整数:"))print( num_1/num_2 )
except ValueError:print("数值错误:程序只能接收整数参数")
except ArithmeticError:print("算术错误")
except Exception:print("未知异常")

该程序中,根据用户输入num_1 和 num_2 值的不同,可能会导致 ValueError、ArithmeticError 异常:

  1. 如果用户输入的 num_1 或者 num_2 是其他字符,而不是数字,会发生 ValueError 异常,try 块会捕获到该类型异常,同时 Python 解释器会调用第一个 except 块处理异常;
  2. 如果用户输入的 num_1 和 num_2 是数字,但 num_2 的值为 0,由于在进行除法运算时除数不能为 0,因此会发生 ArithmeticError 异常,try 块会捕获该异常,同时 Python 解释器会调用第二个 except 块处理异常;
  3. 当然,程序运行过程中,还可能由于其他因素出现异常,try 块都可以捕获,同时 Python 会调用最后一个 except 块来处理。

通过traceback.format_exc()返回异常栈(返回是数据类型是字符串)

 

import tracebackdef func_1():x = 10y = 0try:b = x/yprint(b)except ZeroDivisionError as e: # as 为别名,当一个变量名称太长时可取别名代替简化ei = traceback.format_exc()print(f"出错啦,错误信息:{e},{ei}")print("做完除法后需要执行的代码")出错啦,错误信息:division by zero,Traceback (most recent call last):File "C:\Users\37210\Desktop\Jcmall_study\test_b\b_3.py", line 8, in func_1b = x/y
ZeroDivisionError: division by zero做完除法后需要执行的代码

 常见异常举例

IOError 输入/输出异常;基本上是无法打开文件
TypeError 传入对象类型与要求的不符合
AttributeError 无法访问该对象,一般对象不存在,比如foo.x,但是foo没有属性x
ImportError  无法引入模块或包;基本上是路径问题或名称错误
IndentationError  语法错误(的子类) ;代码没有正确对齐
IndexError  下标索引超出序列边界,比如当x只有三个元素,却试图访问x[5]
KeyError  试图访问字典里不存在的键
NameError  使用一个还未被赋予对象的变量
SyntaxError Python代码非法,一般是语法错误

except 后面可以指定捕获的错误类型,错误类型指定后,如果try:下面的代码抛出的错误类型非该指定的类型,则不会被捕获,程序仍旧会异常终止; 

 

def func_1():x = 10y = 0try:b = x/yprint(b)except ValueError as e:  # 这里对ValueError的异常进行捕获print(f"出错啦,错误信息:{e}")print("做完除法后需要执行的代码")Traceback (most recent call last):File "/Users/fujinjie/PythonProjects/develop_test/buyer_app_autotest/unit_test.py", line 33, in <module>r = func_1()File "/Users/fujinjie/PythonProjects/develop_test/buyer_app_autotest/unit_test.py", line 27, in func_1b = x/y
ZeroDivisionError: division by zero

三、except 捕获多个指定的错误类型 

def func_1():x = 10y = 0try:b = x/yprint(b)except (TypeError,ValueError,ZeroDivisionError) as e:  # 这里对									  ZeroDivisionError的异常进行捕获print(f"出错啦,错误信息:{e}")print("做完除法后需要执行的代码")出错啦,错误信息:division by zero
做完除法后需要执行的代码def func_1():x = 10y = "0"    # 此处y是一个str类型try:b = x/yprint(b)except (TypeError,ValueError,ZeroDivisionError) as e:  # 这里对												TypeError的异常进行捕获print(f"出错啦,错误信息:{e}")print("做完除法后需要执行的代码")出错啦,错误信息:unsupported operand type(s) for /: 'int' and 'str'
做完除法后需要执行的代码

四、try...except...finally

Python异常处理机制还提供了一个 finally 语句,通常用来为 try 块中的程序做扫尾清理工作

注意:finally 只要求和 try 搭配使用,而至于该结构中是否包含 except ,对于 finally 不是必须的

finally 语句的功能是:无论 try 块是否发生异常,最终都要进入 finally 语句,并执行其中的代码块。

def func_1():x = 10y = 0try:b = x/yprint(b)finally:print("无论try中代码是不出现异常,finally中代码始终会被执行")print("继续执行模块中其他代码")def func_2():x = 10y = 1try:b = x/yprint(b)finally:print("无论try中代码是不出现异常,finally中代码始终会被执行")print("继续执行模块中其他代码")

比较上面两个函数 func_1与func_2,func_1中的try代码块会出现异常,func_2中的try代码块未出现异常,但两个函数的finally包裹的子句都得到了执行

五、try...except...else

在原本的

try except

结构的基础上,Python异常处理机制还提供了一个 else 块,也就是原有 try except 语句的基础上再添加一个 else 块,即

try:#...
except:#...
else:#...

使用 else 包裹的代码,只有当 try 块没有捕获到任何异常时,才会得到执行;反之,如果 try 块捕获到异常,即便调用对应的 except 处理完异常,else 块中的代码也不会得到执行。

注意:else 必须和 try except 搭配使用

 

try:result = 20 / int(input('请输入除数:'))print(result)
except ValueError:print('必须输入整数')
except ArithmeticError:print('算术错误,除数不能为 0')
else:print('没有出现异常')
print("继续执行")

try: 下面的代码未发生异常,则执行else: 下面的代码,如果发生异常则执行except: 下面的代码,因此esle: 代码块的执行与否,取决于try: 是否报异常; 

def func_1():x = 10y = 1try:b = x/yprint(b)except:  # except捕获所有类型的异常,即只要有异常就捕获,不区分异常类型print("出现错误异常后,执行这里")else:print("没有异常会执行这里的代码")finally:print("finally中代码始终会被执行")print("做完除法后需要执行的代码")

总结一个

Python异常处理语法结构如下

try:#业务实现代码
except Exception1 as e:#捕获到Exception1异常后执行此代码...
except Exception2 as e:#捕获到Exception2异常后执行此代码...
#可以有多个 except
...
else:#try中未出现异常是执行此处代码,有异常时不会执行
finally :#不管try中代码是否出现异常,此处代码始终会执行...

注:finally必须跟try连用,跟except与else无连用关系;else必须跟try...except...连用

即整个结构try是必须存在的

  • 如果没有 try 块,则不能有后面的 except 块、else 块和 finally 块。但是也不能只使用 try 块,要么使用 try except 结构,要么使用 try finally 结构;
  • except 块、else 块、finally 块都是可选的,当然也可以同时出现;
  • 可以有多个 except 块,多个 except 块必须位于 try 块之后,finally 块必须位于所有的 except 块之后。
  • 要使用 else 块,其前面必须包含 try 和 except。

异常处理执行过程

 

练习:

1、下面代码存在keyError异常,请通过try...except捕获并处理该异常,当错误时print输出“输入的key不存在,请检查key”

goods_inf = {'Id': 10001, 'goods': 'JBL小音响', 'price': 501}
def get_goods_inf(goods:dict, key:str):res = goods[key]return resget_goods_inf(goods=goods_inf, key='id')

2、请优化下面函数,当除数为0时捕获异常并告知用户除数不能为0,当输入的是非数字时捕获异常并提示用户输入的是非数字字符 

def add_num():num1 = int(input('请输入被除数:'))num2 = int(input('请输入除数:'))res = num1/num2return res

 

3、基于add_num函数,请通过try...except...else优化,当未捕获到异常是函数返回res,当捕获到异常时函数一律返回”输入错误,请检查输入并把这个异常类型打印出来“

4、基于add_num函数,请通过finally进行优化,函数始终会通过print输出’add_num函数执行完毕’

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

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

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

相关文章

Ubutu下的Shell操作

前言 在学习Ubuntu系统时&#xff0c;Shell操作是必不可少的知识。本篇文章是记录我学习Linux系统时&#xff0c;Ubutu下的Shell操作&#xff0c;希望我的分享对大家有所帮助&#xff01; 目录 前言 一、什么时是Shell 二、Shell的基本操作 三、常用的Shell命令 1、目录信…

GIS项目实战06:超详细Node.js安装及系统环境配置

简单的说 Node.js 就是运行在服务端的 JavaScript。 Node.js 是一个基于 Chrome JavaScript 运行时建立的一个平台。 Node.js 是一个事件驱动 I/O 服务端 JavaScript 环境&#xff0c;基于 Google 的 V8 引擎&#xff0c;V8 引擎执行 Javascript 的速度非常快&#xff0c;性能…

一区优化直接写:KOA-CNN-BiLSTM-Attention开普勒优化卷积、长短期记忆网络融合注意力机制的多变量回归预测程序!

适用平台&#xff1a;Matlab 2023版及以上 KOA开普勒优化算法&#xff0c;于2023年5月发表在SCI、中科院1区Top顶级期刊《Knowledge-Based Systems》上。 该算法提出时间很短&#xff0c;目前还没有套用这个算法的文献。 同样的&#xff0c;我们利用该新鲜出炉的算法对我们的…

【好用的AI工具Kimi Chat】帮助提高面试效率

一、背景 年前裁员潮&#xff0c;不少人离职找工作&#xff0c;以及年后金三银四&#xff0c;也是求职高峰期。如何更高效的复习技术知识&#xff0c;以及特别是横纵向比对有总结性的问题。本文以面试【测试开发】的岗位为例&#xff0c;对面试题进行拓展&#xff0c;让AI帮助…

从 Vscode 中远程连接 WSL 服务器:可以本地操作虚拟机

从 Vscode 中远程连接 WSL 服务器&#xff1a;可以本地操作虚拟机 1.下载 Vscode Visual Studio Code - Code Editing. Redefined 2.搜索框中输入>wsl&#xff0c;点击 WSL&#xff1a;Connect to WSL using Distro... 3.点击下载好的Ubuntu&#xff0c;当左下角出现图片同…

U-Boot 中使用 nfs 命令加载文件报错指南

目录 问题一问题描述错误原因解决方案 问题二问题描述解决方案 更多内容 在嵌入式 Linux 开发中&#xff0c;我们经常使用 nfs 命令加载服务端的共享文件或者挂载文件系统。关于服务端 NFS 服务的搭建可以参考基于 NFS 的文件共享实现。 U-Boot 也支持了 nfs 命令&#xff0c;…

RabbitMQ数据隔离

1、新建用户 2、登录用户&#xff0c;设置虚拟主机 登录用户只能操作自己的虚拟主机&#xff0c;交换机等&#xff0c;不能操作其他人的&#xff01;&#xff01;&#xff01;

二维码地址门牌管理系统:登记管理新时代

文章目录 前言一、轻松登记&#xff0c;一扫即通二、智能化登记&#xff0c;优势明显三、政府支持与推广四、智能化管理未来展望 前言 二维码门牌管理系统的上线&#xff0c;为市民带来了便捷。系统不仅提升了登记效率&#xff0c;更保障了个人信息安全&#xff0c;成为城市管…

旅游项目day14

其他模块数据初始化 搜索实现 请求一样&#xff0c;但是参数不一样&#xff0c;根据type划分。 后台需要提供一个搜索接口。 请求分发器&#xff1a; 全部搜索 目的地搜索 精确搜索、无高亮展示 攻略搜索 全文搜索、高亮显示、分页 游记搜搜 用户搜索 丝袜哥

【GitHub项目推荐--Spring 教程】【转载】

该项目是一系列小型且直击要害的教程&#xff1a;每个教程都涵盖了 Java 生态系统中一个单一且定义明确的开发领域。 其中一个重点是 Spring Framework - Spring、Spring Boot 和 Spring Security。除了 Spring 之外&#xff0c;这里的模块还涵盖了 Java 的许多方面。 开源地址…

AI大模型开发架构设计(3)——如何打造自己的大模型

文章目录 如何打造自己的大模型1 新时代职场人应用AIGC的5重境界2 人人需要掌握的大模型原理职场人都能听懂的大语音模型的训练过程职场人都能听得懂的大语言模型的Transformer推理过程 3 如何构建自己的大模型需要具备三个方面的能力LangChain是什么&#xff1f;LangChain主要…

【Git不走弯路】(二)提交与分支的本质

1. 前言 提交与分支是Git中两个基本对象&#xff0c;对初学者而言需要花些时间理解。正如我们之前所说&#xff0c;计算机中很多新概念是新瓶装旧酒。计算机技术来源于需求&#xff0c;服务于需求&#xff0c;需求是计算机技术的出发点和落脚点。梳理清楚工程实践中&#xff0…

13、Kafka ------ kafka 消费者API用法(消费者消费消息代码演示)

目录 kafka 消费者API用法消费者API使用消费者API消费消息消费者消费消息的代码演示1、官方API示例2、创建消费者类3、演示消费结果1、演示消费者属于同一个消费者组2、演示消费者不属于同一个消费者组3、停止线程不适用4、一些参数解释 代码生产者&#xff1a;MessageProducer…

雍禾医疗携手国内三甲医院展开合作 雍禾植发助力行业健康发展

根据《都市人群毛发健康消费白皮书》调研显示,国内毛发医疗服务行业市场规模从2021年至2030年将以21.8%的复合年均增长率(CAGR)增长,2030年将达到1381亿元。市场前景广阔的同时,消费需求也在升级迭代。 此前&#xff0c;北京大学人民医院与雍禾医疗共建“北京大学人民医院X雍禾…

有关Quick BI中lod_fixed函数中以MAX()作为过滤条件报错

一、Quick BI中的lod_fixed函数 lod_fixed{维度1[,维度2]...:聚合表达式[:过滤条件]} 作用&#xff1a;使用指定维度进行计算而不引用任何其他维度。其中&#xff0c; 维度1[,维度2]...&#xff1a;声明维度&#xff0c;指定聚合表达式要连接到的一个或多个维度。使用逗号分…

Kafka-消费者-KafkaConsumer分析-ConsumerNetworkClient

前面介绍过NetworkClient的实现&#xff0c;它依赖于KSelector、InFlightRequests、Metadata等组件&#xff0c;负责管理客户端与Kafka集群中各个Node节点之间的连接&#xff0c;通过KSelector法实现了发送请求的功能&#xff0c;并通过一系列handle*方法处理请求响应、超时请求…

0122-2-JavaScript正则表达式

《JavaScript正则表达式》 第一章 正则表达式 字符匹配 正则表达式是匹配模式&#xff0c;要么匹配字符&#xff0c;要么匹配位置&#xff01; 横向匹配 /ab[2,5]/c/g 匹配 abc, abbc,abbbc,abbbbc,abbbbbc&#xff0c;数字连续出现 2 到 5 次&#xff0c;会匹配 2 位、3 位、…

C++ STL之string的使用及模拟实现

文章目录 1. 前言2. 介绍3. string类的使用3.1 string类的构造函数3.2 string类对象的容量操作3.3 string类对象的访问及遍历操作3.4 string类对象的修改操作3.5 string类对象的字符串操作3.6 string类的非成员函数 4. string类的模拟实现 1. 前言 C语言中&#xff0c;字符串是…

地图 - 实现有多条定位,显示多条定位,并且使用一个圆形遮罩层将多条定位进行覆盖

首先&#xff0c;需要在你的index.html模板页面头部加载百度地图JavaScript API代码&#xff0c;密钥可去百度地图开放平台官网申请 <script type"text/javascript" src"//api.map.baidu.com/api?typewebgl&v1.0&ak您的密钥"></script&…

代码随想录 Leetcode1047. 删除字符串中的所有相邻重复项

题目&#xff1a; 代码(首刷自解 2024年1月21日&#xff09;&#xff1a; class Solution { public:string removeDuplicates(string s) {if (s.size() < 2) return s;stack<char> t;for (int i 0; i < s.size(); i) {if (t.empty()) t.push(s[i]);else {if (s[i…