Python 拥有丰富的内置异常,它们都继承自一个共同的基类 BaseException。最常见的异常则继承自 Exception 类。
了解这些异常对于调试和编写健壮的代码至关重要。下面我将它们分为几类进行介绍。
一、最常见的异常(几乎每个程序员都会遇到)
这些是学习 Python 初期就会频繁碰到的异常。
-
SyntaxError(语法错误)- 原因:代码不符合 Python 的语法规则,无法被解析。
- 示例:
if True print("Hello") # 缺少冒号 `:` # 或 print("Hello" # 括号不匹配
-
IndentationError(缩进错误)- 原因:缩进不正确。这是
SyntaxError的一个子类,但因为非常重要且常见,所以单独列出。 - 示例:
if True: print("Hello") # 这一行缩进量不对 # 或混用空格和制表符
- 原因:缩进不正确。这是
-
NameError(名称错误)- 原因:尝试访问一个未定义的变量或函数名。
- 示例:
print(undefined_variable) # 这个变量从未被赋值
-
TypeError(类型错误)- 原因:操作或函数应用于不适当类型的对象。
- 常见场景:
- 对非可迭代对象进行迭代:
for i in 123: - 执行不兼容类型的操作:
‘a’ + 1 - 函数调用时参数数量正确但类型错误:
len(100) - 调用对象不是函数:
a = 1; a()
- 对非可迭代对象进行迭代:
-
ValueError(值错误)- 原因:操作或函数接收到的参数类型正确,但值不合法。
- 示例:
int("abc") # 字符串"abc"无法转换成整数 x = [1, 2, 3] x.index(4) # 4 不在列表里,无法找到其索引
-
IndexError(索引错误)- 原因:序列(如列表、元组、字符串)的索引超出范围。
- 示例:
my_list = [1, 2, 3] print(my_list[5]) # 列表只有3个元素,索引5不存在
-
KeyError(键错误)- 原因:尝试访问字典中不存在的键。
- 示例:
my_dict = {'a': 1} print(my_dict['b']) # 键 'b' 不存在
-
AttributeError(属性错误)- 原因:尝试访问对象没有的属性或方法。
- 示例:
x = 10 x.append(1) # 整数没有 append 方法
-
ModuleNotFoundError(模块未找到错误)- 原因:
import语句无法找到指定的模块。 - 示例:
import non_existent_module
- 原因:
-
ZeroDivisionError(零除错误)- 原因:试图用 0 作为除数。
- 示例:
result = 10 / 0
二、与IO操作相关的异常
在处理文件或输入输出时常见。
-
FileNotFoundError(文件未找到错误)- 原因:尝试打开一个不存在的文件。
- 示例:
with open('non_existent_file.txt', 'r') as f: content = f.read()
-
PermissionError(权限错误)- 原因:没有足够的权限来执行文件操作(如读取、写入、执行)。
- 示例:尝试向一个只读文件写入内容。
-
IsADirectoryError/NotADirectoryError- 原因:试图将一个目录当作文件操作,或反之。
- 示例:
open('/tmp', 'r')(/tmp是一个目录)
三、与迭代和生成器相关的异常
-
StopIteration(迭代停止)- 原因:由迭代器的
__next__()方法引发,表示迭代器中已经没有更多元素了。通常你不需要手动捕获它,因为for循环会自动处理。
- 原因:由迭代器的
-
GeneratorExit(生成器退出)- 原因:当一个生成器被关闭时(例如调用
.close()方法),生成器内部会收到这个异常,以便进行清理工作。
- 原因:当一个生成器被关闭时(例如调用
四、其他重要异常
-
ImportError(导入错误)- 原因:
import语句找到了模块,但无法从中加载某个特定的名称(如函数、类、子模块)。ModuleNotFoundError是它的子类。 - 示例:
from math import non_existent_function
- 原因:
-
RuntimeError(运行时错误)- 原因:一个不归属于任何其他类别的通用错误。它通常表示一个意想不到的问题。
-
KeyboardInterrupt(键盘中断)- 原因:用户按下了中断键(通常是
Ctrl+C)。它继承自BaseException而不是Exception,所以在某些捕获所有Exception的代码中可能不会被捕获。
- 原因:用户按下了中断键(通常是
-
AssertionError(断言错误)- 原因:
assert语句后的条件求值为False。 - 示例:
assert 1 == 2, “One does not equal two!”
- 原因:
-
UnicodeError及其子类(如UnicodeDecodeError,UnicodeEncodeError)- 原因:在编码或解码 Unicode 字符串时发生错误。
如何处理异常:try...except
为了编写健壮的程序,你需要捕获并处理这些异常。
try:
# 可能会出错的代码
num = int(input("请输入一个数字: "))
result = 10 / num
print(f"结果是:{result}")
except ValueError:
# 处理值错误(例如输入了字母)
print("错误:请输入一个有效的数字!")
except ZeroDivisionError:
# 处理零除错误
print("错误:不能除以零!")
except Exception as e:
# 一个宽泛的异常捕获,处理其他所有未预料到的错误
print(f"发生了一个未知错误:{e}")
else:
# 如果没有发生异常,则执行 else 块
print("计算成功!")
finally:
# 无论是否发生异常,finally 块中的代码都会执行
# 常用于清理资源(如关闭文件)
print("程序执行完毕。")
最佳实践:
- 尽量捕获具体的异常,而不是一个宽泛的
except:或except Exception:。 - 使用
as关键字来获取异常对象的详细信息。

被折叠的 条评论
为什么被折叠?



