介绍
在这个实验中,你将学习如何检查 Python 中的函数是否会引发异常。实验首先会探讨异常以及它们如何在函数中出现。你将创建一个可能会引发 ZeroDivisionError 的简单 Python 函数,并观察异常发生时的回溯信息。
接下来,你将实现一个 try-except 块来优雅地处理异常。最后,你将学习如何使用 pytest.raises 来测试一个函数是否会引发特定的异常(可选介绍)。
探索函数中的异常
在这一步中,你将了解异常以及它们如何在 Python 函数中出现。理解异常对于编写健壮可靠的代码至关重要。异常是会打乱程序正常执行流程的事件。它们可能由于各种原因而出现,例如输入无效、文件未找到或网络错误等。
让我们从创建一个可能会引发异常的简单 Python 函数开始。在 LabEx 环境中打开 VS Code 编辑器,并在 ~/project 目录下创建一个名为 exceptions_example.py 的新文件。
## ~/project/exceptions_example.py
def divide(x, y):
return x / y
print(divide(10, 2))
print(divide(5, 0))
在这段代码中:
- 我们定义了一个名为
divide的函数,它接受两个参数x和y,并返回x除以y的结果。 - 我们首先使用参数
10和2调用divide函数,这将导致在控制台输出5.0。 - 然后,我们使用参数
5和0调用divide函数。这将引发ZeroDivisionError,因为不允许除以零。
现在,让我们运行这个脚本。在 VS Code 中打开终端(你可以在“视图” -> “终端”中找到它),并执行以下命令:
python ~/project/exceptions_example.py
你将看到类似如下的输出:
5.0
Traceback (most recent call last):
File "/home/labex/project/exceptions_example.py", line 4, in <module>
print(divide(5, 0))
File "/home/labex/project/exceptions_example.py", line 2, in divide
return x / y
ZeroDivisionError: division by zero
如你所见,第一条 print 语句成功执行,并输出了结果 5.0。然而,当使用 y = 0 调用 divide 函数时,发生了 ZeroDivisionError,程序终止。回溯信息显示了导致异常的函数调用序列,这对调试很有帮助。
这个示例展示了异常如何在函数中出现,以及它们如何打乱程序的正常执行流程。在下一步中,你将学习如何使用 try 和 except 块来处理异常。
实现 try-except 块
在上一步中,你已经看到异常如何导致程序突然终止。为了优雅地处理异常并防止程序崩溃,你可以使用 try 和 except 块。
try 块允许你将可能引发异常的代码段括起来。如果在 try 块内发生异常,程序将跳转到相应的 except 块,在那里你可以处理该异常。
让我们修改 exceptions_example.py 文件,加入一个 try-except 块来处理 ZeroDivisionError。在 VS Code 编辑器中打开 exceptions_example.py 文件,并按如下方式修改:
## ~/project/exceptions_example.py
def divide(x, y):
try:
result = x / y
return result
except ZeroDivisionError:
return "Cannot divide by zero!"
print(divide(10, 2))
print(divide(5, 0))
print(divide(8, 4))
在这段修改后的代码中:
- 我们在
x / y操作周围添加了一个try块。这意味着如果在除法运算期间发生ZeroDivisionError,程序将跳转到except块。 except ZeroDivisionError:行指定我们要处理ZeroDivisionError异常。- 在
except块内,我们返回字符串"Cannot divide by zero!"。这将被打印到控制台,而不是让程序崩溃。
现在,让我们运行修改后的脚本。在 VS Code 中打开终端,并执行以下命令:
python ~/project/exceptions_example.py
你将看到类似如下的输出:
5.0
Cannot divide by zero!
2.0
如你所见,当除以零时,程序不再崩溃。相反,except 块捕获了 ZeroDivisionError,并打印出消息 "Cannot divide by zero!"。然后程序继续执行,最后一条 print 语句也成功执行。
try-except 块还可以用于处理其他类型的异常。例如,你可以使用 try-except 块来处理在尝试对不兼容的数据类型执行操作时可能发生的 TypeError 异常。你还可以有多个 except 块来处理不同类型的异常。
在下一步中,你将学习如何使用 pytest 来测试异常。
使用 pytest.raises 进行测试(可选介绍)
在这个可选步骤中,你将简要了解如何使用 pytest 来测试异常。pytest 是一个流行的 Python 测试框架,它简化了编写和运行测试的过程。
首先,让我们安装 pytest。在 VS Code 中打开终端并运行以下命令:
pip install pytest
此命令将下载并安装 pytest 及其依赖项。
现在,让我们为我们的 divide 函数创建一个测试文件。在 ~/project 目录下创建一个名为 test_exceptions.py 的新文件。
## ~/project/test_exceptions.py
import pytest
from exceptions_example import divide
def test_divide_by_zero():
with pytest.raises(ZeroDivisionError):
divide(5, 0)
def test_divide_valid():
assert divide(10, 2) == 5
在这段代码中:
- 我们从
exceptions_example.py文件中导入了pytest模块和divide函数。 - 我们定义了一个名为
test_divide_by_zero的测试函数。该函数使用pytest.raises来断言调用divide(5, 0)会引发ZeroDivisionError。with pytest.raises(ZeroDivisionError):块确保只有当在该块内引发ZeroDivisionError时,测试才会通过。 - 我们定义了另一个名为
test_divide_valid的测试函数。该函数断言调用divide(10, 2)会返回值5。
要运行这些测试,在 VS Code 中打开终端并执行以下命令:
pytest ~/project/test_exceptions.py
你应该会看到类似如下的输出:
============================= test session starts ==============================
platform linux -- Python 3.10.12, pytest-7.4.4, pluggy-1.3.0
rootdir: /home/labex/project
collected 2 items
test_exceptions.py .. [100%]
============================== 2 passed in 0.01s ===============================
输出显示收集了两个测试,并且两个测试都通过了。这表明我们的 divide 函数的行为符合预期:当除以零时会引发 ZeroDivisionError,当除以非零数时会返回正确的结果。
这是一个使用 pytest 测试异常的非常基础的示例。pytest 还有许多其他功能,可以帮助你编写更全面、更有效的测试。
总结
在本次实验中,你首先探索了 Python 函数中的异常,了解到异常是会打乱程序正常流程的事件。你创建了一个 divide 函数,当除以零时会引发 ZeroDivisionError。运行脚本可以展示异常如何终止程序,并提供用于调试的回溯信息。
本次实验强调了理解异常对于编写健壮代码的重要性,展示了一个可能引发异常的函数的简单示例,以及在异常发生时如何观察所产生的错误和回溯信息。



