异常与异常捕获
异常与异常捕获
异常
异常以及异常类型
异常就是代码运行报错,行业俗语叫bug。
代码运行中一旦遇到异常会直接结束整个程序的运行,我们在编写代码的过程中药尽可能避免。
代码报错有两种:
-
语法错误
语法错误是明眼人一眼能够看出来的,语法这是程序员的基础技能,不容有错
-
逻辑错误
一眼可能看不出来,需要经验积累能感知到可能有的逻辑错误。
比方说,上文变量经过分支可能被赋值为一个字符串类型的数据,但是在后面执行了一个列表的内置方法报错了。
异常信息
python中会执行遇到异常时抛出异常信息,通常包含三个内容
- 异常位置
- 异常类型
- 异常详情
常见异常类型
SyntaxError|NameError|IndexError|KeyError|IndentationError
等等
异常捕获
基础语法结构
我们在执行程序中,有一些语句可能无法预料是否异常,这时就要使用关键字try
和except
来捕获这里的异常。防止程序异常后直接报错而不往后执行了。
try:
一段可能报错的程序
except 异常类型:
print('你这段代码中遇到了异常')
白话文来解释这段程序:尝试一段可能报错的程序,如果产生了except后的异常类型,那么这段程序停止后不会报出异常信息(异常被捕获了),转而执行except关键字下的子代码块。
来看一个例子:
try:
name # name没有被定义,所以这里引用会异常
print('aaa') # 上面遇到异常后,后续的程序不会执行
except NameError: # 捕捉名称错误的异常
print('出现名称异常')
## 运行结果
出现名称异常
其他语法结构
-
查看系统提示的异常信息
try: name except NameError as e: # 我们通常用变量e来存储错误信息 print(e) # name 'name' is not defined
as充当赋值符号,将捕获到的异常,传值给e
-
针对不同的异常类型制定不同的方案
try: l1 = [11,22,3,4] l1[5] name d1 = {'name':'leethon'} d1['age'] except NameError as e: print('名称异常了') # 如果最早遇到名称异常,则执行此代码 except IndexError as e: print('索引异常了,异常信息是:', e) # 如果最早遇到索引异常,则执行此代码 except KeyError as e: print('关键字异常了') # 如果最早遇到关键字异常,则执行此代码
可以多写几个except来捕获不同的异常类型,分别执行不同的策略来应对这种异常。
-
万能异常 Exception/BaseException
try: l1 = [11,22,3,4] l1[5] name d1 = {'name':'leethon'} d1['age'] except Exception as e: # 无论什么异常都能捕捉 print(e) # 无论什么异常都执行同样的代码
-
结合else使用(了解)
try: # 这是一套可能出错的程序,但是没有出错 pass except Exception as e: print(e) else: print('我哪错了(噘嘴)') ## 执行结果 我哪错了(噘嘴)
当尝试执行的代码没有出现任何问题时,则会执行else下的子代码块。
-
结合finally使用
try: f = open('a.txt', 'r', encoding='utf8') ff.read() # 这里可能出错了 f.close() except Exception as e: # 捕捉异常 print(e) # 打印错误信息 else: print('我哪错了(噘嘴)') finally: f.close() # 无论是否捕捉到异常都会执行。 print('我来兜底,解救你的内存')
无论尝试执行的代码是否异常都会执行finally下的子代码,此句可以防止一些需要上下文联系的代码在中间出错时,后续的代码没能执行的情况。
关键字补充(了解)
-
断言 —— assert
assert 条件 后续代码
如果assert后续的条件为真,则正常执行后续代码,不然就抛出异常。
name = 'leethon' assert name == 'lee' # 后面这个条件判定为假,报错AssertionError print('没错是我') # 没有执行
-
主动抛异常 —— raise
name = 'god' if name != 'leethon': raise NameError('爷要罢工') # 运行到这里,抛出异常,异常类型和信息可以自己指定 print('社畜,继续去工作吧') # 运行结果 NameError: 爷要罢工
异常处理应用场景
异常处理虽然可以防止我们的程序报错,但应该尽量少用,因为它该中断还是中断,会影响我们的功能实现,应做到:
- 使用try的次数尽量少
- 一个try下的代码尽量短
try一般用于真的拿不准的时候才会用,一定会报错的程序应该修改,一定不会报错的程序也不该占用监测资源,如:我们在突然断网时会抛出网络异常,这种异常是无法预料的。
try实战小题
结合迭代器的相关知识,实现for循环遍历列表打印
l1 = [111, 222, 333, 444, 555]
ite = l1.__iter__()
try:
while True:
print(ite.__next__())
except StopIteration:
pass
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)