Python 异常是什么?
在之前的 Python 学习中,经常可以看到程序运行后会出现各种报错,举个简单的例子。
>>> print(a)
Traceback (most recent call last):
File '<pyshell#0>', line 1, in <module>
print(a)
NameError: name 'a' is not defined这种情况,小伙伴们是不是感到很熟悉呢?当检测到一个 bug(即错误)时,Python 解释器就无法继续执行了,反而出现了一些错误的提示,这就是所谓的 “异常” 。程序产生异常时,首先会打印错误信息,然后中断程序的运行。
Python 中的异常,其实是一个事件,这个事件会在程序运行过程中发生。一般情况下,Python 无法正常处理程序时就会发生异常。Python 中的每一个异常都是一些类的实例,因此我们可以使用对应的方法进行捕获,使得错误可以被处理,而不是让整个程序失败。
对于一些简单的程序来说,是否对异常进行处理,并不显得那么重要。但是随着代码量的增加,比如在一个大型程序中发生异常,如果没有做恰当的处理,就很可能导致整个程序崩溃。由于程序崩溃了,你也崩溃了,最后 boss(老板)也崩溃了。
Python 常见异常
了解常见的 Python 异常,可以帮助我们快速地判断该异常是什么,以便更快地解决异常。在 Python 中,常见的异常如下表所示。
| 异常 | 说明 |
|---|---|
| ValueError | 值的类型或范围不符合 |
| NameError | 变量不存在 |
| AttributeError | 属性不存在 |
| KeyError | 键不存在 |
| SyntaxError | 语法错误 |
| TypeError | 类型错误 |
| ZeroDivisionError | 除数为 0 |
| IndexError | 索引超出范围 |
| IOError | 输入输出异常 |
对于表中这些异常,你不需要记住,但是要尽量认得。事实上,除了上表列出的这些,Python 还有很多其他的异常,如果你是刚开始接触 Python,只需要掌握上面这些就够了。
1. ValueError 异常
当传递给函数或方法的参数值不符合预期类型或范围时,就会抛出 NameError 异常,例如:
>>> int('abc')
Traceback (most recent call last):
File "D:\my-test\python-test\test.py", line 1, in <module>
int('abc')
ValueError: invalid literal for int() with base 10: 'abc'2. NameError 异常
当尝试访问一个不存在的变量时,就会抛出 NameError 异常,例如:
>>> print(a)
Traceback (most recent call last):
File '<pyshell#13>', line 1, in <module>
print(a)
NameError: name 'a' is not defined3. AttributeError 异常
当尝试访问对象一个不存在的属性时,就会抛出 AttributeError 异常,例如:
>>> colors = []
>>> print(colors.name)
Traceback (most recent call last):
File '<pyshell#3>', line 1, in <module>
colors.name
AttributeError: 'list' object has no attribute 'name'4. KeyError 异常
当尝试访问字典中一个不存在的键时,就会抛出 KeyError 异常,例如:
>>> nums={'one': 1, 'two': 2, 'three': 3}
>>> print(nums['four'])
Traceback (most recent call last):
File '<pyshell#14>', line 1, in <module>
print(dict['four'])
KeyError: 'four'5. SyntaxError 异常
当 Python 语法发生错误时,就会抛出 SyntaxError 异常,例如:
>>> students=['Jack': 1001]
SyntaxError: invalid syntax对于字典,我们应该使用大括号 “{}” ,而这里却使用中括号 “[]” ,因此会抛出 SyntaxError 异常。
6. TypeError 异常
当对不同类型的数据进行计算时,就会抛出 TypeError 异常,例如:
>>> print(1 + '2')
Traceback (most recent call last):
File '<pyshell#16>', line 1, in <module>
print(1+'2')
TypeError: unsupported operand type(s) for +: 'int' and 'str'7. ZeroDivisionError 异常
我们都知道,除数是不能为 0 的,否则会抛出 ZeroDivisionError 异常,例如:
>>> result = 666 / 0
Traceback (most recent call last):
File '<pyshell#17>', line 1, in <module>
result=666/0
ZeroDivisionError: division by zero8. IndexError 异常
当索引超出序列(列表、元组、字符串)的范围时,就会抛出 IndexError 异常,例如:
>>> nums = [1, 2, 3, 4, 5]
>>> print(nums[8])
Traceback (most recent call last):
File '<pyshell#5>', line 1, in <module>
print(nums[8])
IndexError: list index out of range9. IOError 异常
IOError 指的是系统输入输出时产生的异常,例如打开一个不存在的文件就会引发 FileNotFoundError。这个 FileNotFoundError 就是 IOError 的子类,例如:
>>> file = open(r'D:\hello.txt')
Traceback (most recent call last):
File '<pyshell#0>', line 1, in <module>
file=open(r'D:\hello.txt')
FileNotFoundError: [Errno 2] No such file or directory: 'D:\\hello.txt'Python 处理异常
程序员之间流传着一个老笑话:“写代码占了编程工作量的 90%,而调试 bug 占了剩余工作量的 90%。” bug 是比较恼人的,如果一个大型程序出现难以排查的 bug,很可能让你几天都夜不能寐。
前面了解了常见的异常,接下来几节中将介绍一些有用的技巧,以帮助你更快、更容易地处理这些 “异常(bug)”。
关于 “bug” 的故事
可能你会觉得很奇怪,为什么会使用 “bug(小虫子)”(如下图所示)这个单词来形容程序中出现的错误呢?其实这来源于计算机先驱 Grace Murray Hopper 的故事。

1946 年,当 Hopper 退役后,她加入了哈佛大学计算实验室,在那里她继续研究计算机 Mark II 和 Mark III。在研究过程中,她发现了 Mark II 中的一个错误,而这个错误是一只小虫子(其实是飞蛾)被困在继电器中所导致的。而后,这个 “bug” 被霍珀小心翼翼地移下继电器,并用胶带粘到了日志簿上,成为了计算机的第一个 “bug”。
