如何在 Python 3 中将 CSV 编写器与 GZIP 文件一起使用?

Posted

技术标签:

【中文标题】如何在 Python 3 中将 CSV 编写器与 GZIP 文件一起使用?【英文标题】:How do I use CSV Writers with GZIP files in Python 3? 【发布时间】:2015-01-28 03:07:42 【问题描述】:

我正在尝试将一些代码从 Python 2.7 移植到 Python 3。2to3 工具适用于基本语法和包更改,但现在我们遇到了一些奇怪的副作用。

我有以下代码块。它使用 gzip 模块打开一个临时文件名。

f = NamedTemporaryFile(delete=False)
f.close()
fn = f.name + '.gz'
os.rename(f.name, fn)
fz = gzip.open(fn, 'wb')
writer = csv.writer(fz, delimiter='\t', lineterminator=lt)
for row in table:
    writer.writerow(row)
fz.close()

问题是执行此操作会出现以下错误:

File "/usr/local/Cellar/python3/3.4.2_1/Frameworks/Python.framework/Versions/3.4/lib/python3.4/gzip.py", line 343, in write
self.crc = zlib.crc32(data, self.crc) & 0xffffffff
TypeError: 'str' does not support the buffer interface

我尝试将 gzip 文件打开为“w”而不是“wb”,但无济于事。我猜 gzip 模块需要一个字节数组,但 CSV Writer 不提供或不会提供除字符串以外的任何内容。

人们如何在 Python 3 中做到这一点?

编辑:我应该提到这个代码块在 Python 2.7 中执行没有问题。

【问题讨论】:

你应该在写模式下试试。 fz = gzip.open(fn, 'w', newline='') 不,我得到与上面相同的ValueError。我正在考虑根据文档将其重构为包装在 TextIOWrapper 中的 GzipFile。他们在这方面不是很详细。 将模式改为wt,而不是wb 我添加评论作为答案! ;) 也可以使用writer.writerows(table),不用自己迭代其他table 【参考方案1】:

您需要将gzip的模式更改为wt

fz = gzip.open(fn, 'wt')

gzip.open()bz2.open()还有一个鲜为人知的特点是它们可以分层 在以二进制模式打开的现有文件之上。例如,这有效:

import gzip
f = open('somefile.gz', 'rb')
with gzip.open(f, 'rt') as g:
    text = g.read()

这允许 gzip 和 bz2 模块处理各种类似文件的对象,例如 套接字、管道和内存中的文件。

【讨论】:

是的,Python 3 意味着您必须非常小心用于打开文件的标志。伙计,真头疼。 @WineSoaked :) 是的,gzip.open()bz2.open() 的一个鲜为人知的功能是它们可以分层在以二进制模式打开的现有文件之上。 您应该使用gzip.open(fn, 'wt', newline='') 打开以进行写入,否则 csv 的换行处理可能会受到影响(即:如果 csv 条目具有嵌入的换行符)。 如果要在同一个脚本中上传该文件,则需要关闭文件处理程序f,否则上传的gzip文件会损坏。因此,只需在 with 块之后执行 f.close() 即可。

以上是关于如何在 Python 3 中将 CSV 编写器与 GZIP 文件一起使用?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 python 3.6.9 中将 dbf 转换为 csv?

如何在python中将csv转换为json?

如何在 QML 中将 @pyqtSlot 装饰器与其他装饰器一起使用?

使用python在django中将数据库转换为csv

如何在python中将json转换为csv?

如何在 Python 中将多个 .txt 文件转换为 .csv 文件