Python异常机制
一、异常机制概述
Python异常机制本质:当程序出现异常时,程序能够安全退出、处理完后继续执行的机制。
Python引进了很多异常类,异常类定义中包含了该类异常的信息和对异常进行处理的方法。
一切皆对象,异常也采用对象的方式来处理。
二、try...except异常处理结构
try块包含可能引发异常的代码,except块用来捕捉和处理异常。
try块中如果没有异常,跳过except块继续执行;如果发生异常,跳到except块处理,处理完后继续执行后续代码。
▶ 示例:遇到异常的执行顺序
#测试简单的0不能做除数异常
try:
print("step1")
a = 3/0
print("step2")
except BaseException as e:
print("step3")
print(e)
print("step4")
▶ 示例:循环输入数字,异常处理
while True:
try:
x = int(input("请输入一个数字:"))
print("您输入的数字是", x)
if x == 88:
print("退出程序")
break
except:
print("异常:输入的不是一个数字")
三、try...多个except结构
建议尽量捕获可能出现的多个异常(按照先子类后父类的顺序),针对性写出异常处理代码。
为避免遗漏,可以在最后增加 BaseException。
▶ 示例:多个except结构
try:
a = input("请输入被除数:")
b = input("请输入除数:")
c = float(a) / float(b)
print(c)
except ZeroDivisionError:
print("异常:除数不能为0")
except TypeError:
print("异常:除数和被除数都应该为数值类型")
except BaseException as e:
print(e)
print(type(e))
四、try...except...else结构
如果try块中没有抛出异常,则执行else块;如果抛出异常,则执行except块,不执行else块。
▶ 示例:try...except...else结构
try:
a = input("请输入被除数:")
b = input("请输入除数:")
c = float(a) / float(b)
except BaseException as e:
print(e)
else:
print("除的结果是:", c)
五、try...except...finally结构
finally块无论是否发生异常都会被执行,通常用来释放try块中申请的资源。
return语句一般不放到try、except、else、finally块中,建议放到方法最后。
▶ 示例:try...except...finally简单测试
try:
a = input("请输入一个被除数:")
b = input("请输入一个除数:")
c = float(a) / float(b)
except BaseException as e:
print(e)
else:
print(c)
finally:
print("我是finally中的语句,无论发生异常与否,都执行!")
print("程序结束!")
▶ 示例:finally中保证关闭文件资源
try:
f = open("d:/a.txt", 'r')
content = f.readline()
print(content)
except BaseException as e:
print(e)
finally:
f.close() #释放资源
print("step4")
▶ 示例:return和异常结构的正确处理方式
def test01():
print("step1")
try:
x = 3/0
except:
print("step2")
print("异常:0不能做除数")
finally:
print("step4")
print("step5")
return "e" #建议放到方法最后
print(test01())
六、常见异常
Python中的异常都派生自 BaseException 类,以下列出常见的异常类型。
异常名称 | 说明 |
SyntaxError | 语法错误 |
NameError | 尝试访问未声明的变量 |
ZeroDivisionError | 除数为0错误 |
ValueError | 数值错误(如float转换失败) |
TypeError | 类型错误(如int+str) |
AttributeError | 访问对象不存在的属性 |
IndexError | 索引越界异常 |
KeyError | 字典的关键字不存在 |
ArithmeticError | 所有数值计算错误的基类 |
ImportError | 导入模块/对象失败 |
IndentationError | 缩进错误 |
IOError | 输入/输出操作失败 |
KeyboardInterrupt | 用户中断执行(Ctrl+C) |
MemoryError | 内存溢出错误 |
OSError | 操作系统错误 |
RuntimeError | 一般的运行时错误 |
StopIteration | 迭代器没有更多的值 |
UnicodeDecodeError | Unicode解码时的错误 |
UnicodeEncodeError | Unicode编码时错误 |
WindowsError | 系统调用失败 |
七、with上下文管理
with上下文管理可以自动管理资源,在with代码块执行完毕后自动还原进入该代码之前的现场或上下文。
不论何种原因跳出with块,不论是否有异常,总能保证资源正常释放。
在文件操作、网络通信相关的场合非常常用。
▶ 示例:with上下文管理文件操作
with open("d:/bb.txt") as f:
for line in f:
print(line)
八、traceback模块和异常日志
使用 traceback 模块可以打印详细的异常信息,也可以将异常信息写入日志文件。
▶ 示例:使用traceback模块打印异常信息
import traceback
try:
print("step1")
num = 1/0
except:
traceback.print_exc()
▶ 示例:使用traceback将异常信息写入日志文件
#coding=utf-8
import traceback
try:
print("step1")
num = 1/0
except:
with open("d:/a.log", "a") as f:
traceback.print_exc(file=f)
九、自定义异常类
自定义异常类一般都是运行时异常,通常继承 Exception 或其子类即可。
命名一般以 Error、Exception 为后缀。
自定义异常由 raise 语句主动抛出。
▶ 示例:自定义异常类和raise语句
#测试自定义异常类
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__":
age = int(input("输入一个年龄:"))
if age < 1 or age > 150:
raise AgeError(age)
else:
print("正常的年龄:", age)
上一篇:文件操作(1)
下一篇:python基础概念


