目录
Exception—异常机制
python中,引进了很多用来描述和处理异常的类
Python异常处理机制简单说明
Python中一切皆对象,异常也采用对象的方式来处理。处理过程:
1.抛出异常:在执行一个方法时,如果发生异常,则这个方法生成代表该异常的一个对象,停止当前执行路径,并把异常对象提交给解释器
2.捕获异常:解释器得到该异常后,寻找相关代码处理该异常
解释器解决的关键:定位
当发生异常时,解释器会报相关的错误信息,并在控制台打印相关错误信息,只需按照从上至下的顺序,即可追溯错误发生的过程
try...except...包含的多种结构
try...一个except...结构
try...except是常见的异常处理结构。结构如下:
try:
被监控的可能引发异常的语句块
except BaseException [as e]:
异常处理语句块
# 测试try……except……结构
# 循环输入数字,若不是数字则抛出异常,输入21结束循环
while True:
try:
a = int(input("请输入一个数字:"))
print(a)
if a == 21:
break
except BaseException as e:
print(e)
print("输入异常!!!")
print("循环结束!!!")
'''
请输入一个数字:23
输出:23
请输入一个数字:g
输出:invalid literal for int() with base 10: 'g'
输出:输入异常!!!
请输入一个数字:21
输出:21
输出:循环结束!!!
'''
执行时,若try块中未引发异常,则跳过except语句块继续执行后续代码;若执行时在try中发现了异常,则跳过try语句中的后续代码,跳到相应的except块中处理异常,异常处理完毕后继续处理except之后的别的代码
try...多个except结构
上面的BaseException可以捕获所有的异常,但从经典理论考虑,一般建议尽量捕获可能出现的多个异常(按照先子类后父类的顺序)并且针对性的写出异常处理代码,为了避免遗漏可能出现的情况,可在最后添加BaseException。结构如下:
try:
被监控的可能引发异常的语句块
except Exception1 :
处理Exception1的语句块
except Exception2 :
处理Exception2的语句块
……
except BaseException :
处理可能遗漏的异常的语句块
# 测试try……多个except的基本用法
try:
a = int(input("请输入一个除数:"))
b = int(input("请输入一个被除数:"))
c = float(a)/float(b)
print(c)
except ZeroDivisionError :
print("异常,0不可做为被除数")
except ValueError :
print("异常,输入的值不是数字,不能进行除法操作")
except NameError :
print("自变量不存在")
except BaseException as e:
print(e)
print("输出结束!!!")
'''
请输入一个除数:5
请输入一个被除数:0
输出:异常,0不可做为被除数
输出:输出结束!!!
请输入一个除数:g
输出:异常,输入的值不是数字,不能进行除法操作
输出:输出结束!!!
'''
try...except...else结构
try...except...else结构中增加了“else块”,如果try中没有抛出异常,则执行else语句块,如果try中抛出异常,则执行except语句块,不执行else语句块,其二者是并列且竞争关系。结构如下:
try:
被监控的可能引发异常的语句块
except Exception1 :
处理Exception1的语句块
except Exception2 :
处理Exception2的语句块
……
except BaseException :
处理可能遗漏的异常的语句块
else:
try正常执行后执行的语句块
# 测试try……except……else结构
try:
f = open("d:\\a.txt","r")
content = f.readline()
print(content)
except BaseException as e:
print(e)
else:
print("成功找到{0}文件".format(f))
f.close()
'''
输出:
1234566
成功找到<_io.TextIOWrapper name='d:\\a.txt' mode='r' encoding='cp936'>文件
'''
try...except...finally结构
try...except...finally结构中,finally块无论是否发生异常都会被执行,通常用来释放try中申请的资源,结构如下:
try:
被监控的可能引发异常的语句块
except BaseException [as e]:
异常处理语句块
finally:
语句块
# 测试try……except……finally语句
import os
try:
f = open("e:\\a.txt", "r")
content = f.readline()
print(content)
except BaseException as e:
print(e)
finally:
if os.path.exists("e:\\a.txt"):
f.close()
print("程序执行结束!!!")
'''
输出:
[Errno 2] No such file or directory: 'e:\\a.txt'
程序执行结束!!!
'''
return语句和异常处理问题
由于return有两种作用:结束方法的运行和返回值。
一般不把return放到异常处理结构中,而是放到方法最后
常见异常的汇总
Python中的异常都派生自BaseException类,异常汇总:
异常名称 | 解释说明 |
---|---|
ArithmeticError | 所有数值计算错误的基类 |
AssertionError | 判断语句失败 |
AttributeError | 对象没有这个属性 |
BaseException | 所有异常的基类 |
DepressionWarning | 关于被弃用的特征的警告 |
EnvironmentError | 操作系统错误的基类 |
EOFError | 无内建输入,到达eof标记 |
Exception | 常规错误的基类 |
FloatingPointError | 浮点计算错误 |
FutureWarning | 关于构造将来语义会有改变的警告 |
GeneratorExit | 生成器(generator)发生异常 通知退出 |
ImportError | 导入模块对象失败 |
IndentationError | 缩进错误 |
IndexError | 序列中无此索引 |
IOError | 输入\输出 操作失败 |
KeyboardInderrupt | 用户中断执行(通常是出入^c) |
KeyError | 映射中没有这个键 |
LookupError | 无效数据查询的基类 |
MemoryError | 内存溢出错误(对于Python解释器不是致命的) |
NameError | 未声明\初始化对象(没有属性) |
NotImplementedError | 尚未实现的方法 |
OSError | 操作系统错误 |
OverflowError | 数值计算超过最大限度 |
PendingDeprecationWarning | 关于特性将会被废弃的警告 |
OverflowWarning | 旧的关于自动提升为长整型的警告 |
ReferenceError | 弱引用(weak reference)试图访问已经垃圾回收了的对象 |
RuntimeError | 一般的运行时错误 |
RuntimeWarning | 可疑的运行时行为(runtime behavior)的警告 |
StandardError | 所有的内建标准异常的基类 |
StopIteration | 迭代器无更多的值 |
SyntaxError | Python语法错误 |
SyntaxWarning | 可疑的语法的警告 |
SystemError | 一般的解释器系统错误 |
SystemExit | 解释器请求退出 |
TabError | Tab 和空格混用 |
TypeError | 对类型无效的操作 |
UNboundLocalError | 访问未初始化的本地变量 |
UnicodeDecodeError | Unicode解码时的错误 |
UnicodeEncodeError | Unicode编码时错误 |
UnicodeError | Unicode相关的错误 |
UnicodeTranslateError | Unicode转换时错误 |
UserWarning | 用户代码生成的警告 |
ValueError | 传入无效的参数 |
Warning | 警告的基类 |
WindowsError | 系统调用失败 |
ZeroDivisionError | 除(取模)0(所有数据类型) |
with上下文管理
try...一系列结构中,finally块由于是否发生异常都会执行,通常用来释放资源
结构:
with context_expr [as var]:
语句块
with上下文管理可以自动管理资源,在with代码块执行完毕后自动还原进入该代码之前的现场或上下文,不论何种原因跳出with块,不论是否存在异常,总能保证资源正常释放。在文件操作、网络通信相关的场合非常常用
# 测试with语句(不是取代try……except……finally,而是为了在文件操作管理和网络通信方面使用)
with open("E:\\codeblock..cc\\1.cpp\\a.txt", "r") as f:
content = f.readline()
print(content)
'''
输出:
姓名=小王,年龄=20,性别=男
'''
traceback模块
使用traceback模块打印异常信息
import traceback
try:
print("xxxxxx")
num = 1/0
except:
traceback.print_exc()
# 测试traceback模块用法
import traceback
try:
print("x"*10)
a = 1/0
except BaseException:
with open("E:\\codeblock..cc\\1.cpp\\a.txt","a") as f:
traceback.print_exc(file=f)
'''
输出:
XXXXXXXXXX
'''
自定义异常类
程序开发中,有时也需要自己定义异常类,其一般情况是运行时异常通常继承Exception或其子类即可,命名一般以Error、Exception为后缀
自定义异常有raise语句主动抛出
# 测试自定义异常类
class AgeError(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 < 0 or age > 150:
raise AgeError(age)
else:
print(age)
'''
请输入一个年龄:200
输出:Traceback (most recent call last):
File "E:\python project\py project 01\mypy20.py", line 15, in <module>
raise AgeError(age)
__main__.AgeError: 200,年龄错误,年龄应在1-150之间
'''