0

我编写了一个 Python 脚本,它将生成一系列图表,然后生成包含这些图表的 PDF 报告。目的是这将在服务器上生成。我正在使用 ReportLab 生成 PDF。该脚本正在运行 Windows 7 的计算机上运行。

在脚本的开头,设置了一个存储 ReportLab flowables 的列表和一个存储每个图形的路径的列表。

Story = []
FigList = []

每个图形都是使用 Matplotlib 生成的,并保存为 PNG。图像被附加到 Story 中,文件的路径被添加到 FigList 中。

fig = plt.figure(1)
ax = fig.add_subplot(1, 1, 1)
ax.plot(x, y)
fname = "figure.png"
fig.savefig(fname)
FigList.append(fname)
Story.append(Image(fname))

对许多图像(总共大约 10 - 15 个)重复此操作。在脚本结束时,文档被构建

doc = SimpleDocTemplate("report.pdf",
                        pagesize=A4,
                        rightMargin=cm,
                        leftMargin=cm,
                        topMargin=cm,
                        bottomMargin=cm)

doc.build(Story)

在此之后,我希望删除所有使用创建的 PNG 文件

for f in FigList:
    if os.path.exists(f): os.remove(f)

但是,我收到以下错误

WindowsError:[错误 32] 该进程无法访问该文件,因为它正在被另一个进程使用:'image.png'

我在这里假设文档创建过程是在单独的线程中执行的,因此当脚本尝试删除图形文件时,文件管理器仍将它们标记为打开。

重要的是在进程完成之前删除这些图像文件,因为该进程可能会执行多次,因此临时图像文件很快就会占用太多空间。

有没有办法让脚本在继续删除文件之前等待所有图像关闭?

4

2 回答 2

3

似乎可以通过Image(...)在将变量附加到变量之前对其进行分配然后将其Story删除来解决该问题。如果我们考虑问题中的示例,则此修改变为

fig = plt.figure(1)
ax = fig.add_subplot(1, 1, 1)
ax.plot(x, y)
fname = "figure.png"
fig.savefig(fname)
FigList.append(fname)
img = Image(fname)
Story.append(img)
del img

注意:这与创建的文件对象无关savefig()

于 2012-06-18T15:02:15.647 回答
0

您是否尝试过将打开的文件包装在一个with语句中?通常python在离开with子句后会为你关闭文件。

编辑:看起来您fig.savefig(fname)可能会返回图像文件对象。如果这是正确的,您可以尝试在完成后对它返回的每个文件对象调用 close。

于 2012-06-12T14:18:56.040 回答