
本文探讨了在Sphinx doctest中使用包含Matplotlib图形示例的文档字符串时,如何避免因`plt.show()`导致的测试阻塞问题。核心策略是优化Matplotlib绘图函数,使其接受可选的`ax`参数,并将图形显示逻辑(`plt.show()`)从函数内部移除,从而允许doctest在非交互模式下顺利运行,并提升函数的可重用性与灵活性。
在Python项目中使用Sphinx生成文档并利用其doctest功能进行代码示例验证是一种高效实践。然而,当函数的文档字符串中包含Matplotlib绘图示例,并且函数内部调用了plt.show()时,doctest在执行这些示例时会因图形窗口的弹出而暂停,需要手动关闭窗口才能继续,这极大地影响了自动化测试流程。本教程将详细介绍如何通过优化Matplotlib绘图函数来解决这一问题。
原始的绘图函数通常会直接在函数内部创建图形并调用plt.show()来显示它。例如,考虑以下函数:
import matplotlib.pyplot as plt
def plot_numbers_original(x):
"""
显示一组数字的折线图。
Parameters
----------
x : list
要绘制的数字列表。
Example
-------
>>> import your_module_name # 假设函数位于 your_module_name 模块中
>>> x = [1, 2, 5, 6, 8.1, 7, 10.5, 12]
>>> your_module_name.plot_numbers_original(x)
"""
_, ax = plt.subplots()
ax.plot(x, marker="o", mfc="red", mec="red")
ax.set_xlabel("Label for x-axis")
ax.set_ylabel("Label for y-axis")
ax.set_title("Title of the plot")
plt.show() # 这一行是导致doctest阻塞的根源当Sphinx make doctest命令执行到your_module_name.plot_numbers_original(x)时,plt.show()会被调用,弹出一个Matplotlib图形窗口。在非交互式或自动化测试环境中,这个窗口不会自动关闭,导致测试进程挂起,需要用户手动干预才能继续。这与自动化测试的初衷相悖。
解决此问题的核心策略是将绘图逻辑与图形显示逻辑解耦。具体做法是让绘图函数接受一个可选的Matplotlib Axes 对象作为参数。如果用户提供了Axes对象,函数就在该对象上绘图;如果未提供,函数则自行创建一个新的Figure和Axes。最重要的是,从函数内部移除plt.show()的调用。
以下是优化后的函数示例:
import matplotlib.pyplot as plt
def plot_numbers(x, *, ax=None):
"""
显示一组数字的折线图。
Parameters
----------
x : list
要绘制的数字列表。
ax : matplotlib.axes.Axes, optional
可选的Matplotlib Axes对象,用于在该坐标轴上绘图。
如果未提供,函数将创建一个新的Figure和Axes。
Example
-------
>>> import your_module_name # 假设函数位于 your_module_name 模块中
>>> x = [1, 2, 5, 6, 8.1, 7, 10.5, 12]
>>> result_ax = your_module_name.plot_numbers(x)
>>> # 在doctest中,我们通常不显示图形。我们可以验证函数是否正确地设置了坐标轴属性。
>>> len(result_ax.lines) # 验证图中绘制的线条数量
1
>>> result_ax.get_xlabel() # 验证x轴标签
'Label for x-axis'
>>> result_ax.get_title() # 验证图表标题
'Title of the plot'
>>> # 如果需要在交互式环境或特定测试中显示图形,可以这样做:
>>> # fig, my_ax = plt.subplots()
>>> # your_module_name.plot_numbers(x, ax=my_ax)
>>> # plt.show() # 在需要显示时由外部调用
"""
if ax is None:
_, ax = plt.subplots() # 如果没有提供ax,则创建一个新的Figure和Axes
ax.plot(x, marker="o", mfc="red", mec="red")
ax.set_xlabel("Label for x-axis")
ax.set_ylabel("Label for y-axis")
ax.set_title("Title of the plot")
return ax # 返回Axes对象,以便外部进行进一步操作或显示关键改动点:
这种重构带来了多方面的好处,显著提升了代码质量和开发效率:
以上就是在Sphinx doctest中处理Matplotlib图形示例的策略的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号