异常:程序中的意外情况
编写程序时,我们都希望它们能够顺利运行,但总会遇到一些意想不到的情况,导致程序出错。这些错误在 Python 中被称为异常 (Exception)。简单来说,异常就是在程序运行过程中发生的错误信号,Python 解释器会创建一个异常对象来描述这个错误。
异常对象包含了错误类型、文件名、出错行号等关键信息,方便我们定位和解决问题。常见的 Python 内置异常包括:
ImportError
: 导入模块失败时发生。ZeroDivisionError
: 除数为零时发生。NameError
: 尝试访问未定义的变量时发生。ValueError
: 函数接收到的参数类型正确,但值不合法时发生。例如,将字符串 "abc" 转换为整数。IndexError
: 尝试访问列表中不存在的索引时发生。KeyError
: 尝试访问字典中不存在的键时发生。TypeError
: 运算符或函数应用于不兼容类型的对象时发生。IndentationError
: 缩进错误时发生。
除了 Python 解释器自动抛出的异常,我们也可以使用 raise
语句或 assert
语句在代码中主动触发异常。
raise
语句:手动抛出异常
raise
语句允许我们在程序中主动抛出一个异常。通常,我们会附带自定义的错误信息,以便更好地理解错误的原因。
让我们通过一个例子来理解 raise
的用法。假设我们需要编写一个程序,接收用户输入的两个数字 a
和 b
,并计算 a/b
的结果。
初版代码
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
语句来处理除数为零的情况。
改进代码
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
异常的信息不够明确。我们可以添加自定义的错误信息,让异常更有意义。
更进一步的代码
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
。
示例
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
语句的语法如下:
assert condition, message
其中,condition
是需要检查的表达式,message
是可选的错误信息。
示例
a = 3
b = 4
assert a == b, "a 必须等于 b"
c = 5
print(c) #如果assert失败,这句不会被执行
由于 a
不等于 b
,assert
语句会抛出 AssertionError
异常。
运行结果
Traceback (most recent call last):
File "<stdin>", line 3, in <module>
AssertionError: a 必须等于 b
如果 assert
后面的表达式为 True
,则程序会继续执行。
示例
a = 3
b = 3
assert a == b, "a 必须等于 b"
c = 5
print(c)
运行结果
5
可以看到,当 a
等于 b
时,程序顺利执行,并输出了 c
的值。
总而言之,raise
用于主动抛出异常,表示程序遇到了无法正常处理的错误;assert
用于在开发阶段检查代码中的假设,帮助我们尽早发现潜在的问题。