Skip to content

异常:程序中的意外情况

编写程序时,我们都希望它们能够顺利运行,但总会遇到一些意想不到的情况,导致程序出错。这些错误在 Python 中被称为异常 (Exception)。简单来说,异常就是在程序运行过程中发生的错误信号,Python 解释器会创建一个异常对象来描述这个错误。

异常对象包含了错误类型、文件名、出错行号等关键信息,方便我们定位和解决问题。常见的 Python 内置异常包括:

  • ImportError: 导入模块失败时发生。
  • ZeroDivisionError: 除数为零时发生。
  • NameError: 尝试访问未定义的变量时发生。
  • ValueError: 函数接收到的参数类型正确,但值不合法时发生。例如,将字符串 "abc" 转换为整数。
  • IndexError: 尝试访问列表中不存在的索引时发生。
  • KeyError: 尝试访问字典中不存在的键时发生。
  • TypeError: 运算符或函数应用于不兼容类型的对象时发生。
  • IndentationError: 缩进错误时发生。

除了 Python 解释器自动抛出的异常,我们也可以使用 raise 语句或 assert 语句在代码中主动触发异常。

raise 语句:手动抛出异常

raise 语句允许我们在程序中主动抛出一个异常。通常,我们会附带自定义的错误信息,以便更好地理解错误的原因。

让我们通过一个例子来理解 raise 的用法。假设我们需要编写一个程序,接收用户输入的两个数字 ab,并计算 a/b 的结果。

初版代码

python
a = int(input("请输入 a: "))
b = int(input("请输入 b: "))
print("a/b =", a/b)

这段代码在 b 为 0 时会产生 ZeroDivisionError

运行结果

请输入 a: 10
请输入 b: 0
Traceback (most recent call last):
  File "<stdin>", line 3, in <module>
ZeroDivisionError: division by zero

为了使程序更加健壮,我们可以使用 raise 语句来处理除数为零的情况。

改进代码

python
a = int(input("请输入 a: "))
b = int(input("请输入 b: "))
if b == 0:
    raise Exception()
print("a/b =", a/b)

现在,当 b 等于 0 时,程序会抛出一个 Exception 异常。

运行结果

请输入 a: 10
请输入 b: 0
Traceback (most recent call last):
  File "<stdin>", line 4, in <module>
Exception

虽然程序不再崩溃,但 Exception 异常的信息不够明确。我们可以添加自定义的错误信息,让异常更有意义。

更进一步的代码

python
a = int(input("请输入 a: "))
b = int(input("请输入 b: "))
if b == 0:
    raise Exception("除数不能为零!")
print("a/b =", a/b)

运行结果

请输入 a: 10
请输入 b: 0
Traceback (most recent call last):
  File "<stdin>", line 4, in <module>
Exception: 除数不能为零!

现在,异常信息更加清晰,方便我们定位错误。

除了使用通用的 Exception,我们还可以根据实际情况抛出特定类型的异常,例如 ValueError

示例

python
a = int(input("请输入 a: "))
b = int(input("请输入 b: "))
if b == 0:
    raise ValueError("除数不能为零!")
print("a/b =", a/b)

运行结果

请输入 a: 10
请输入 b: 0
Traceback (most recent call last):
  File "<stdin>", line 4, in <module>
ValueError: 除数不能为零!

assert 语句:代码中的安全卫士

assert 语句是一种调试工具,主要用于在开发阶段检查代码中的假设是否成立。如果 assert 后面的表达式为 False,则会抛出 AssertionError 异常,提醒开发者存在潜在的问题。

assert 语句的语法如下:

python
assert condition, message

其中,condition 是需要检查的表达式,message 是可选的错误信息。

示例

python
a = 3
b = 4
assert a == b, "a 必须等于 b"
c = 5
print(c) #如果assert失败,这句不会被执行

由于 a 不等于 bassert 语句会抛出 AssertionError 异常。

运行结果

Traceback (most recent call last):
  File "<stdin>", line 3, in <module>
AssertionError: a 必须等于 b

如果 assert 后面的表达式为 True,则程序会继续执行。

示例

python
a = 3
b = 3
assert a == b, "a 必须等于 b"
c = 5
print(c)

运行结果

5

可以看到,当 a 等于 b 时,程序顺利执行,并输出了 c 的值。

总而言之,raise 用于主动抛出异常,表示程序遇到了无法正常处理的错误;assert 用于在开发阶段检查代码中的假设,帮助我们尽早发现潜在的问题。