3.1.异常
异常处理机制
异常处理无外乎几件事:
- 断言(assert)
- 抛错(raise)
- 检查(try)
- 捕获(except)
- 处理(except, else, finally)
异常即是一个事件,该事件会在程序执行过程中发生,影响了程序的正常执行。一般情况下,在Python无法正常处理程序时就会发生一个异常。当Python脚本发生异常时,异常会从发生异常的位置向程序上层传播。例如异常从函数向外传播到调用函数的地方,如果在这里没有被捕获,则继续向上传播,如果一直都没有被捕获,则传播到程序的最顶层,即主程序(全局作用域)。如果在主程序中也没有处理异常的程序,python将调用默认的异常处理程序,自动匹配异常的类型,然后中止程序并显示栈跟踪信息。
# 在cause_error函数中抛出异常
def cause_error():
raise Exception("Somrthing is wrong")
# 在call_cause_error函数中调用cause_error函数
def call_cause_error():
cause_error()
def deal_error():
try:
cause_error()
except:
print("Exception handled")
call_cause_error()
---------------------------------------------------------------------------Exception
Traceback (most recent call last)<ipython-input-1-eb81f11bf5d9> in
<module>
----> 1 call_cause_error()
<ipython-input-1-ec5e029839e0> in call_cause_error()
1 def call_cause_error():
----> 2 cause_error()
3
<ipython-input-1-11326a099618> in cause_error()
1 def cause_error():
----> 2 raise Exception("Somrthing is wrong")
3
Exception: Somrthing is wrong
deal_error()
Exception handled
如你所见,cause_error中引发的异常依次从cause_error和call_cause_error向外传播,最终导致显示一条栈跟踪信息。调用deal_error时,异常在传播到deal_error时被捕获,并被这里的try/except语句处理。
异常是Python对象,表示一个错误。异常可以作为类被定义, 也可以人为引发异常。
异常处理语句
try: # try语句中代码首先被运行
<statement>
except: # 捕获任何在try中引发的异常
<statement>
except <name>: # 捕获在try中引发的<name>异常
<statement>
except <name>,<data>: # 如果引发了'name'异常,获得附加的数据
<statement>
except (<name1>,<name2>...): # 捕获列出的多个异常
<statement>
else: # 如果没有异常发生
<statement>
finally: # 退出try时总会执行
<statement>
raise # 人为引发错误
assert <judgement> # 断言 判断为假的话会引发AssertionError
raise语句
使用raise...from...语句来提供自己的异常上下文,也可以使用None来禁止上下文。
# 默认输出异常上下文
try:
1/0
except ZeroDivisionError:
raise ValueError
---------------------------------------------------------------------------ZeroDivisionError
Traceback (most recent call last)<ipython-input-1-56b5a2b441f0> in
<module>
1 try:
----> 2 1/0
3 except ZeroDivisionError:
ZeroDivisionError: division by zero
During handling of the above exception, another exception occurred:
ValueError Traceback (most recent call
last)<ipython-input-1-56b5a2b441f0> in <module>
2 1/0
3 except ZeroDivisionError:
----> 4 raise ValueError
5
ValueError:
# 自定义上下文
try:
1/0
except ZeroDivisionError:
raise ValueError from ZeroDivisionError
---------------------------------------------------------------------------ZeroDivisionError
Traceback (most recent call last)ZeroDivisionError:
The above exception was the direct cause of the following exception:
ValueError Traceback (most recent call
last)<ipython-input-1-00ed5b67ecd8> in <module>
2 1/0
3 except ZeroDivisionError:
----> 4 raise ValueError from ZeroDivisionError
5
ValueError:
# 禁止上下文
try:
1/0
except ZeroDivisionError:
raise ValueError from None
---------------------------------------------------------------------------ValueError
Traceback (most recent call last)<ipython-input-1-d9388897f61c> in
<module>
2 1/0
3 except ZeroDivisionError:
----> 4 raise ValueError from None
ValueError:
内置异常
异常名称 | 描述 |
---|---|
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 | 用户代码生成的警告 |