异常处理
异常和错误
导引
软件程序在运行过程中,非常可能遇到刚刚提到的这些问题,我们称之为异常,英文是:Exception,意思是例外。遇到这些例外情况,或者叫异常
异常机制本质
所谓异常处理,就是指程序在出现问题时依然可以正确的执行剩余的程序,而不会因为异常而终止程序执行。
python 中内建异常类的继承层次:

异常的结构
python 中一切都是对象,异常也采用对象的方式来处理。处理过程:
- 抛出异常:在执行一个方法时,如果发生异常,则这个方法生成代表该异常的一个对象,停止当前执行路径,并把异常对象提交给解释器。
- 捕获异常:解释器得到该异常后,寻找相应的代码来处理该异常。
a = 3 / 0
>>>
>>>
D:\Software\ANACONDA\python.exe D:/Code_output/Python/python基础/day1.py
Traceback (most recent call last): #Traceback追溯,追根溯源。most recent call last最后一次调用。
File "D:/Code_output/Python/python基础/day1.py", line 1, in <module>
a = 3 / 0
ZeroDivisionError: division by zero # 0作为除数了
Process finished with exit code 1
解决异常问题的态度
解决每一个遇到的异常, 建议大家遵循如下三点:
- 不慌张, 细看信息, 定位错误。 看清楚报的错误信息, 并定位发生错误的地方。
- 百度并查看十个相关帖子。 将异常类信息进行百度, 至少查看十个以上的相关帖子。
- 以上两步仍然无法解决, 找老师和同学协助解决。
异常解决的关键: 定位
当发生异常时, 解释器会报相关的错误信息, 并会在控制台打印出相关错误信息。 我们只需按照从上到下的顺序即可追溯(Trackback) 错误发生的过程, 最终定位引起错误的那一行代码
def a():
num = 1/0
def b():
a()
def c():
b()
c()
>>>
>>>
D:\Software\ANACONDA\python.exe D:/Code_output/Python/python基础/Python400集第一季源代码/代码异常/my01.py
Traceback (most recent call last):
File "D:/Code_output/Python/python基础/Python400集第一季源代码/代码异常/my01.py", line 14, in <module>
c()
File "D:/Code_output/Python/python基础/Python400集第一季源代码/代码异常/my01.py", line 11, in c
b()
File "D:/Code_output/Python/python基础/Python400集第一季源代码/代码异常/my01.py", line 8, in b
a()
File "D:/Code_output/Python/python基础/Python400集第一季源代码/代码异常/my01.py", line 5, in a
num = 1/0
ZeroDivisionError: division by zero #其实只有这个错误,前面的都是过程
Process finished with exit code 1
异常处理结构
try…一个 except 结构
try 块包含着可能引发异常的代码, except 块则用来捕捉和处理发生的异常。 执行的时候, 如果 try 块中没有引发异常, 则跳过 ecept 块续执行后续代码; 执行的时候, 如果 try块中发生了异常, 则跳过 try 块中的后续代码, 跳到相应的 except 块中处理异常; 异常处理完后, 继续执行后续代码。
处理结构

#coding=utf-8
print("step0")
try:
print("step1")
a = 3/0
print("step2")
except BaseException as e: #e就是一个错误类型对象
print("step3")
print(e)
print(type(e))
print("end!!!!")
while True:
try:
x = int(input('Please enter a number:'))
print('The number is :',x)
if x == 88 :
print('Quit')
break
except BaseException as e:
print(e)
print('Wrong! You shoule enter a number !!')
print('If you want to quit, please enter number 88')
print('Program end')
try…多个 except 结构
针对不同的异常,执行不同的操作
按照先子类后父类的顺序

#coding=utf-8
#测试try...多个except结构
try:
a = input("请输入一个被除数:")
b = input("请输入一个除数:")
c = float(a)/float(b)
print(c)
except ZeroDivisionError:
print("异常。不能除以0")
except ValueError:
print("异常。不能将字符串转化成数字")
except NameError:
print("异常。变量不存在")
except BaseException as e:
print(e)
try…except…else 结构
try…except…else 结构增加了“ else 块” 。 如果 try 块中没有抛出异常, 则执行 else 块。 如果try 块中抛出异常, 则执行 except 块, 不执行 else 块。
#coding=utf-8
#测试try...except...else结构
try:
a = input("请输入一个被除数:")
b = input("请输入一个除数:")
c = float(a)/float(b)
except BaseException as e:
print(e)
else:
print(c)
print("程序结束!")
try…except…finally 结构
try…except…finally 结构中, finally 块无论是否发生异常都会被执行; 通常用来释放 try 块中申请的资源。
#coding=utf-8
#测试try...except...else...finally结构
try:
a = input("请输入一个被除数:")
b = input("请输入一个除数:")
c = float(a)/float(b)
except BaseException as e:
print(e)
else:
print(c)
finally:
print("我是finally中的语句,无论发生异常与否,都执行!")
print("程序结束!")
#coding=utf-8
#测试finally
try:
f = open("d:/adddd.txt","r")
content = f.readline()
print(content)
except:
print("文件未找到")
finally:
print("run in finally。关闭资源")
try:
f.close()
except BaseException as e:
print(e)
print("程序执行结束!")
return 语句和异常处理问题
def test01():
print("step1")
try:
x = 3/0
# return "a"
except:
print("step2")
print("异常: 0 不能做除数")
#return "b"
finally:
print("step4")
#return "d"
print("step5")
return "e" #一般不要将 return 语句放到 try、 except、 else、 finally 块中, 会发生一些意想不到的错误。 建议放到方法最后。
print(test01())
常见异常的解决
- SyntaxError: 语法错误
- NameError: 尝试访问一个没有申明的变量
- ZeroDivisionError: 除数为 0 错误(零除错误)
- ValueError: 数值错误
- TypeError: 类型错误
- AttributeError: 访问对象的不存在的属性
- IndexError: 索引越界异常
- KeyError: 字典的关键字不存在
常见异常汇总



with 上下文管理
finally 块由于是否发生异常都会执行, 通常我们放释放资源的代码。 其实, 我们可以通过 with 上下文管理, 更方便的实现释放资源的操作。

with 上下文管理可以自动管理资源, 在 with 代码块执行完毕后自动还原进入该代码之前的现场或上下文。 不论何种原因跳出 with 块, 不论是否有异常, 总能保证资源正常释放。 极大的简化了工作, 在文件操作、 网络通信相关的场合非常常用。
#coding=utf-8
#测试with上下文管理(with不是用来取代try...except...finally结构的,只是作为补充。方便我们再文件管理、网络通信时的开发)
with open("d:/a.txt","r") as f:
content = f.readline()
print(content)
print("程序执行结束!")
trackback 模块
追溯模块,帮助我们更方便的打印异常信息
#coding=utf-8
#测试trackback模块的使用
import traceback
try:
print("step1")
num = 1/0
except:
traceback.print_exc()
#######将异常信息输出到指定的文件中########
try:
print("step1")
num = 1/0
except:
with open("d:/a.txt","a") as f:
traceback.print_exc(file=f)
自定义异常类
程序开发中, 有时候我们也需要自己定义异常类。 自定义异常类一般都是运行时异常, 通常继承 Exception 或其子类即可。 命名一般以 Error、 Exception 为后缀。
自定义异常由 raise 语句主动抛出。
#coding=utf-8
#测试自定义异常类
class AgeError(Exception): #继承Exception
def __init__(self,errorInfo):
Exception.__init__(self)
self.errorInfo = errorInfo
def __str__(self):
return str(self.errorInfo)+",年龄错误!应该在1-150之间"
############测试代码################
if __name__ == "__main__": #如果为True,则模块是作为独立文件运行,可以执行测试代码
age = int(input("输入一个年龄:"))
if age<1 or age>150:
raise AgeError(age)
else:
print("正常的年龄:",age)
Pycharm 开发环境的调试
关键:设置断点
调试视图(debug):shift+F9
调试操作


这篇博客详细介绍了Python的异常处理机制,包括try-except结构、异常定位、常见异常类型及处理,以及with上下文管理和自定义异常。强调了解决异常问题时的定位技巧和PyCharm的调试方法。
1264

被折叠的 条评论
为什么被折叠?



