如何检查 Python 函数是否会引发异常

PythonPythonBeginner
立即练习

💡 本教程由 AI 辅助翻译自英文原版。如需查看原文,您可以 切换至英文原版

简介

在这个实验中,你将学习如何检查 Python 中的函数是否会引发异常。实验首先会探讨异常以及它们如何在函数中出现。你将创建一个可能会引发 ZeroDivisionError 的简单 Python 函数,并观察异常发生时的回溯信息。

接下来,你将实现一个 try-except 块来优雅地处理异常。最后,你将学习如何使用 pytest.raises 来测试一个函数是否会引发特定的异常(可选介绍)。


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL python(("Python")) -.-> python/ErrorandExceptionHandlingGroup(["Error and Exception Handling"]) python/ErrorandExceptionHandlingGroup -.-> python/catching_exceptions("Catching Exceptions") python/ErrorandExceptionHandlingGroup -.-> python/raising_exceptions("Raising Exceptions") subgraph Lab Skills python/catching_exceptions -.-> lab-559520{{"如何检查 Python 函数是否会引发异常"}} python/raising_exceptions -.-> lab-559520{{"如何检查 Python 函数是否会引发异常"}} end

探索函数中的异常

在这一步中,你将了解异常以及它们如何在 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 的函数,它接受两个参数 xy,并返回 x 除以 y 的结果。
  • 我们首先使用参数 102 调用 divide 函数,这将导致在控制台输出 5.0
  • 然后,我们使用参数 50 调用 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,程序终止。回溯信息显示了导致异常的函数调用序列,这对调试很有帮助。

这个示例展示了异常如何在函数中出现,以及它们如何打乱程序的正常执行流程。在下一步中,你将学习如何使用 tryexcept 块来处理异常。

实现 try-except 块

在上一步中,你已经看到异常如何导致程序突然终止。为了优雅地处理异常并防止程序崩溃,你可以使用 tryexcept 块。

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) 会引发 ZeroDivisionErrorwith 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。运行脚本可以展示异常如何终止程序,并提供用于调试的回溯信息。

本次实验强调了理解异常对于编写健壮代码的重要性,展示了一个可能引发异常的函数的简单示例,以及在异常发生时如何观察所产生的错误和回溯信息。