一、异常简介
- 程序在运行过程中可能会出现一些错误。比如: 使用了不存在的索引,两个不同类型的数据相加…这些错误我们称之为异常
- 处理异常:程序运行时出现异常,目的并不是让我们的程序直接终止!Python是希望在出现异常时,我们可以编写代码来对异常进行处理
- 异常即是一个事件,该事件会在程序执行过程中发生,影响了程序的正常执行。
- 一般情况下,在Python无法正常处理程序时就会发生一个异常。
- 异常是Python对象,表示一个错误。
- 当Python脚本发生异常时我们需要捕获处理它,否则程序会终止执行。
二、异常传播
- 当在函数中出现异常时,如果在函数中对异常进行了处理,则异常不会在进行传播。如果函数中没有对异常进行处理,则异常会继续向函数调用传播。如果函数调用处处理了异常,则不再传播异常,如果没有处理则继续向调用处传播。直到传递到全局作用域(主模块)如果依然没有处理,则程序终止,并显示异常信息。
- 当程序运行过程中出现异常以后,所有异常信息会保存到一个异常对象中。
- 当异常传播时,实际上就是异常对象抛给了调用处
三、异常处理语法:try语句
try:
代码块(可能出现错误的语句)
except 异常类型 as 异常名
代码块(出现错误以后的处理方式)
except 异常类型 as 异常名:
代码块(出现错误以后的处理方式)
except 异常类型 as 异常名:
代码块(出现错误以后的处理方式)
......
else:
代码块(没出错时要执行的语句)
finally:
代码块(是否出错该代码块都会执行)
- try是必须的 else有没有都可以
- except和finally至少有一个
try的工作原理:
- 当开始一个try语句后,python就在当前程序的上下文中作标记,这样当异常出现时就可以回到这里,try子句先执行,接下来会发生什么依赖于执行时是否出现异常。
- 如果当try后的语句执行时发生异常,python就跳回到try并执行第一个匹配该异常的except子句,异常处理完毕,控制流就通过整个try语句(除非在处理异常时又引发新的异常)。
- 如果在try后的语句里发生了异常,却没有匹配的except子句,异常将被递交到上层的try,或者到程序的最上层(这样将结束程序,并打印默认的出错信息)。
- 如果在try子句执行时没有发生异常,python将执行else语句后的语句(如果有else的话),然后控制流通过整个try语句。
四、异常对象
- 异常对象的基类:Exception
- 用 “except Exception as e:”,获取错误信息:print(e)
五、常见异常类型
异常名称 | 描述 |
---|
BaseException | 所有异常的基类 |
SystemExit | 解释器请求退出 |
KeyboardInterrupt | 用户中断执行(通常是输入^C) |
Exception | 常规错误的基类 |
StopIteration | 迭代器没有更多的值 |
GeneratorExit | 生成器(generator)发生异常来通知退出 |
StandardError | 所有的内建标准异常的基类 |
ArithmeticError | 所有数值计算错误的基类 |
FloatingPointError | 浮点计算错误 |
OverflowError | 数值运算超出最大限制 |
ZeroDivisionError | 除(或取模)零 (所有数据类型) |
AssertionError | 断言语句失败 |
AttributeError | 对象没有这个属性 |
EOFError | 没有内建输入,到达EOF 标记 |
EnvironmentError | 操作系统错误的基类 |
IOError | 输入/输出操作失败 |
OSError | 操作系统错误 |
WindowsError | 系统调用失败 |
ImportError | 导入模块/对象失败 |
LookupError | 无效数据查询的基类 |
IndexError | 序列中没有此索引(index) |
KeyError | 映射中没有这个键 |
MemoryError | 内存溢出错误(对于Python 解释器不是致命的) |
NameError | 未声明/初始化对象 (没有属性) |
UnboundLocalError | 访问未初始化的本地变量 |
ReferenceError | 弱引用(Weak reference)试图访问已经垃圾回收了的对象 |
RuntimeError | 一般的运行时错误 |
NotImplementedError | 尚未实现的方法 |
SyntaxError | Python 语法错误 |
IndentationError | 缩进错误 |
TabError | Tab 和空格混用 |
SystemError | 一般的解释器系统错误 |
TypeError | 对类型无效的操作 |
ValueError | 传入无效的参数 |
UnicodeError | Unicode 相关的错误 |
UnicodeDecodeError | Unicode 解码时的错误 |
UnicodeEncodeError | Unicode 编码时错误 |
UnicodeTranslateError | Unicode 转换时错误 |
Warning | 警告的基类 |
DeprecationWarning | 关于被弃用的特征的警告 |
FutureWarning | 关于构造将来语义会有改变的警告 |
OverflowWarning | 旧的关于自动提升为长整型(long)的警告 |
PendingDeprecationWarning | 关于特性将会被废弃的警告 |
RuntimeWarning | 可疑的运行时行为(runtime behavior)的警告 |
SyntaxWarning | 可疑的语法的警告 |
UserWarning | 用户代码生成的警告 |
详见《Python 异常处理》
六、案例
6.1测试一下正常执行的try:
print('hello')
try:
print("测试try 1")
print(6/2)
print("测试try 2")
except:
print("测试try 3")
print('大兄弟出错了.....')
else:
print("测试try 4")
print('程序正常执行没有错误.....')
finally:
print("测试try 5")
print('java')
6.2测试一下有异常的try:
print('hello')
try:
print("测试try 1")
print(6/0)
print("测试try 2")
except:
print("测试try 3")
print('大兄弟出错了.....')
else:
print("测试try 4")
print('程序正常执行没有错误.....')
finally:
print("测试try 5")
print('java')
6.3异常的传播:
6.3.1异常未处理,再到程序中止
def fn():
print('hello fn')
print(6 / 0)
def fn2():
print('hello fn2')
fn()
def fn3():
print('hello fn3')
fn2()
fn3()
6.3.2中途异常被处理
def fn():
print('hello fn')
print(6 / 0)
def fn2():
print('hello fn2 调用fn前')
fn()
print('hello fn2 调用fn后')
def fn3():
print('hello fn3 调用fn2前')
try:
fn2()
print('hello fn3 调用fn2 try 内')
except:
pass
print('hello fn3 调用fn2后')
def fn4():
print('hello fn4 调用fn3前')
fn3()
print('hello fn4 调用fn3后')
fn4()