Python 异常处理全攻略:从入门到精通
Python 提供两大特性处理程序中的意外错误并增强调试能力:
- 异常处理:本教程重点讲解。Python 标准异常列表见下表。
- 断言:详见“Python 断言”教程。
标准异常列表
| 序号 | 异常名及说明 |
|---|---|
| 1 | Exception:所有异常的基类。 |
| 2 | StopIteration:迭代器无下一个对象时抛出。 |
| 3 | SystemExit:sys.exit() 引发。 |
| 4 | StandardError:除 StopIteration 和 SystemExit 外所有内置异常的基类。 |
| 5 | ArithmeticError:数值计算错误基类。 |
| 6 | OverflowError:计算超出数值类型最大限制。 |
| 7 | FloatingPointError:浮点计算失败。 |
| 8 | ZeroDivisionError:除数或模数为零。 |
| 9 | AssertionError:assert 语句失败。 |
| 10 | AttributeError:属性引用或赋值失败。 |
| 11 | EOFError:raw_input() 或 input() 无输入且到达 EOF。 |
| 12 | ImportError:import 失败。 |
| 13 | KeyboardInterrupt:用户中断(通常 Ctrl+C)。 |
| 14 | LookupError:查找错误基类。 |
| 15 | IndexError:序列中无此索引。 |
| 16 | KeyError:字典中无此键。 |
| 17 | NameError:局部或全局命名空间找不到标识符。 |
| 18 | UnboundLocalError:访问未赋值的局部变量。 |
| 19 | EnvironmentError:Python 环境外错误基类。 |
| 20 | IOError:I/O 操作失败(如打开不存在文件)。 |
| 21 | OSError:操作系统相关错误。 |
| 22 | SyntaxError:Python 语法错误。 |
| 23 | IndentationError:缩进错误。 |
| 24 | SystemError:解释器内部问题,但不退出。 |
| 25 | SystemExit:sys.exit() 退出解释器,未处理则终止。 |
| 26 | TypeError:操作或函数用于不适当的数据类型。 |
| 27 | ValueError:内置函数参数类型正确但值无效。 |
| 28 | RuntimeError:不属于其他类别的错误。 |
| 29 | NotImplementedError:抽象方法未在子类实现。 |
Python 断言
断言是可开关的理智检查,类似 raise-if-not 语句:表达式为假则抛出异常。由 assert 语句实现(Python 1.5 引入)。常用于函数入口检查输入、出口检查输出。
assert 语句
语法:assert Expression[, Arguments]。表达式为假时抛出 AssertionError,可用 try-except 捕获,否则终止程序并输出回溯。
示例
将开尔文温度转华氏度,负温度则报错:
#!/usr/bin/python
def KelvinToFahrenheit(Temperature):
assert (Temperature >= 0), "Colder than absolute zero!"
return ((Temperature - 273) * 1.8) + 32
print(KelvinToFahrenheit(273))
print(int(KelvinToFahrenheit(505.78)))
print(KelvinToFahrenheit(-5))
输出:
32.0
451
Traceback (most recent call last):
File "test.py", line 9, in
print(KelvinToFahrenheit(-5))
File "test.py", line 4, in KelvinToFahrenheit
assert (Temperature >= 0), "Colder than absolute zero!"
AssertionError: Colder than absolute zero!
什么是异常?
异常是程序执行期间发生的事件,打断正常指令流。Python 脚本遇到无法处理的情况会引发异常,异常是代表错误的 Python 对象。脚本引发异常后,必须立即处理,否则终止退出。
处理异常
将可疑代码放入 try: 块,后跟 except: 处理块。
语法
try:
# 你的操作
except ExceptionI:
# 处理 ExceptionI
except ExceptionII:
# 处理 ExceptionII
...
else:
# 无异常时执行
要点:
- 单个
try可有多个except,应对不同异常类型。 - 可提供通用
except捕获所有异常。 else块在try无异常时执行,适合放不需要保护的代码。
示例 1:正常写入文件
#!/usr/bin/python
try:
fh = open("testfile", "w")
fh.write("This is my test file for exception handling!!")
except IOError:
print("Error: can't find file or read data")
else:
print("Written content in the file successfully")
fh.close()
输出:
Written content in the file successfully
示例 2:无写权限触发异常
#!/usr/bin/python
try:
fh = open("testfile", "r")
fh.write("This is my test file for exception handling!!")
except IOError:
print("Error: can't find file or read data")
else:
print("Written content in the file successfully")
输出:
Error: can't find file or read data
无异常类型的 except 子句
try:
# 操作
except:
# 处理任意异常
else:
# 无异常执行
此方式捕获所有异常,但不利于定位根因,非良好实践。
多异常的 except 子句
try:
# 操作
except (Exception1[, Exception2[,...ExceptionN]]):
# 处理列表中任一异常
else:
# 无异常执行
try-finally 子句
finally: 块中的代码无论是否发生异常都会执行。语法:
try:
# 操作
finally:
# 总会执行
else 不能与 finally 共用。
示例
#!/usr/bin/python
try:
fh = open("testfile", "w")
fh.write("This is my test file for exception handling!!")
finally:
print("Error: can't find file or read data")
若无写权限,输出:
Error: can't find file or read data
更规范写法:
#!/usr/bin/python
try:
fh = open("testfile", "w")
try:
fh.write("This is my test file for exception handling!!")
finally:
print("Going to close the file")
fh.close()
except IOError:
print("Error: can't find file or read data")
try 块抛出异常时,立即跳转到 finally 块;执行完 finally 后异常重新抛出,由上层 try-except 处理。
异常参数
异常可携带参数,提供额外错误信息。在 except 中用变量接收:
try:
# 操作
except ExceptionType, Argument:
# 打印 Argument 值
单异常时变量跟在异常名后;多异常时跟在元组后。变量接收异常值(通常含错误字符串、错误号、位置),可为单值或元组。
示例
#!/usr/bin/python
def temp_convert(var):
try:
return int(var)
except ValueError, Argument:
print("The argument does not contain numbers\n", Argument)
temp_convert("xyz")
输出:
The argument does not contain numbers
invalid literal for int() with base 10: 'xyz'
引发异常
使用 raise 语句引发异常。语法:
raise [Exception [, args [, traceback]]]
Exception 为异常类型(如 NameError),args 为参数值(可选,默认 None),traceback 为回溯对象(可选,极少用)。
示例
def functionName(level):
if level < 1:
raise "Invalid level!", level
# 引发异常后以下代码不执行
注意:捕获异常时 except 必须引用相同异常(类对象或字符串)。捕获上例异常需写:
try:
# 业务逻辑
except "Invalid level!":
# 异常处理
else:
# 其他代码
用户自定义异常
通过继承内置异常类创建自定义异常。示例继承 RuntimeError:
class Networkerror(RuntimeError):
def __init__(self, arg):
self.args = arg
引发并捕获:
try:
raise Networkerror("Bad hostname")
except Networkerror, e:
print(e.args)
Python
- 精通Python数据类型:实战指南
- 精通Python运算符:全面指南
- 精通Python Pass语句:实战指南
- 精通Python函数参数:位置、关键字与默认参数
- 精通 Python 字典:创建、操作与进阶技巧
- 精通 Python 错误与内置异常
- 精通 Python 异常处理:try、except、else 与 finally 详解
- 精通 Python 自定义异常:实战指南
- 精通 Python 迭代器:工作原理与自定义构建
- Python 闭包详解:嵌套函数如何捕获变量
- 精通 Python datetime:日期、时间与时区实战指南
- 精通 Python 异常处理:try、except、finally 与 raise 高效用法