在 Python 中直接从内存中保存多个对象以压缩

Posted

技术标签:

【中文标题】在 Python 中直接从内存中保存多个对象以压缩【英文标题】:save multiple objects to zip directly from memory in Python 【发布时间】:2019-04-10 16:02:22 【问题描述】:

我想保存多个对象,例如数字,在循环中直接创建到一个 zip 文件,而不将它们保存在目录中。

目前我将这些数字保存在一个文件夹中,然后压缩它们。

    import matplotlib.pyplot as plt
    from zipfile import ZipFile

    for i in range(10):
        plt.plot([i, i])
        plt.savefig('fig_' + str(i) + '.png')
        plt.close()

    image_list = []
    for file in os.listdir(save_path):
        if file.endswith(".png"):
            image_list.append(os.path.join(save_path, file))

    with ZipFile(os.path.join(save_path, 'export.zip'), 'w') as zip:
        for file in image_list:
            zip.write(file)

如果回答是肯定的,有没有办法对任何类型的对象做同样的事情,还是取决于对象类型?

非常感谢

【问题讨论】:

ZipFile.writestr()。拆分函数名,参数data可以是bytes或者字符串,如果是字符串,在存储前会被编码为UTF-8。 您好,目前尚不清楚如何在最终的 zip 文件中使用相对名称保存每个图形,即使我创建了一个空的 zip 文件然后附加 zipfile.ZipFile('zipfile_append.zip', mode='a') 【参考方案1】:

    @BoarGules 指出[Python.Docs]: ZipFile.writestr(zinfo_or_arcname, data, compress_type=None, compresslevel=None) 允许创建包含内存内容的 zip 文件成员

    [SO]: how to save a pylab figure into in-memory file which can be read into PIL image? (@unutbu's answer) 显示如何将绘图图像内容保存在内存中 ([Matplotlib]: matplotlib.pyplot.savefig),通过[Python.Docs]: class io.BytesIO([initial_bytes])

    你所要做的,就是结合以上2个

code00.py

#!/usr/bin/env python

import sys
import matplotlib.pyplot as plt
import zipfile
import io


def main(*argv):
    zip_file_name = "export.zip"
    print("Creating archive: :s".format(zip_file_name))
    with zipfile.ZipFile(zip_file_name, mode="w") as zf:
        for i in range(3):
            plt.plot([i, i])
            buf = io.BytesIO()
            plt.savefig(buf)
            plt.close()
            img_name = "fig_:02d.png".format(i)
            print("  Writing image :s in the archive".format(img_name))
            zf.writestr(img_name, buf.getvalue())


if __name__ == "__main__":
    print("Python 0:s 1:dbit on 2:s\n".format(" ".join(item.strip() for item in sys.version.split("\n")), 64 if sys.maxsize > 0x100000000 else 32, sys.platform))
    rc = main(sys.argv[1:])
    print("\nDone.")
    sys.exit(rc)

输出

[cfati@CFATI-5510-0:e:\Work\Dev\***\q055616877]> dir /b
code00.py

[cfati@CFATI-5510-0:e:\Work\Dev\***\q055616877]> "e:\Work\Dev\VEnvs\py_pc064_03.08.07_test0\Scripts\python.exe" code00.py
Python 3.8.7 (tags/v3.8.7:6503f05, Dec 21 2020, 17:59:51) [MSC v.1928 64 bit (AMD64)] 64bit on win32

Creating archive: export.zip
  Writing image fig_00.png in the archive
  Writing image fig_01.png in the archive
  Writing image fig_02.png in the archive

Done.

[cfati@CFATI-5510-0:e:\Work\Dev\***\q055616877]> dir /b
code00.py
export.zip

您会注意到,(图像)文件根本没有压缩(存档大小略大于成员大小的总和)。要启用压缩,还要将 compression=zipfile.ZIP_DEFLATED 传递给 ZipFile 的初始化程序。

【讨论】:

@AlessandroBitetto:这能回答你的问题吗?

以上是关于在 Python 中直接从内存中保存多个对象以压缩的主要内容,如果未能解决你的问题,请参考以下文章

如何从内存中删除多个熊猫(python)数据帧以节省 RAM?

下载多个文件并以编程方式在客户端压缩它们

从 SD 卡中获取图像,压缩,然后将其保存回 SD?

如何在 Python 中最好地保存多个类实例?更新:如何腌制包含 osgeo.ogr 对象的类实例?

python——面向对象

python自动化开发学习-8 面向对象进阶