CSV模块的编写者不会让我写二进制文件

时间:2011-03-18 22:09:05

标签: python csv python-3.x

我打算在打开文件时使用'w'标签,但它会使行间隔两倍,导致读取无效。所以我发现更改为'wb'将是正确的格式。现在我正在使用'wb'标志,我无法使csv.writer.writerow()工作。我已经编码了所有的字符串,并且因为我一直收到这个错误而丢失了。我看到的所有问题都说这里的b'string'或myString.encode('ascii')解决了我得到的错误,但它并没有为我解决。这就是我所拥有的:

    dataWriter = csv.writer(open(fileName, 'wb'))
    for i in range(self.ui.table.rowCount()):
        rowData = [self.ui.table.item(i,0).text().encode('utf-8')\
        ,self.ui.table.item(i,1).text().encode('utf-8')\
        ,self.ui.table.item(i,2).text().encode('utf-8')\
        ,self.ui.table.item(i,3).text().encode('utf-8')\
        ,self.ui.table.item(i,4).text().encode('utf-8')]
        dataWriter.writerow(rowData)

我认为哪个会起作用,但它仍然会给我以下错误: “TypeError:必须是字节或缓冲区,而不是str” 在“dataWriter.writerow(rowData)。

这一行

任何帮助都会被贬低。 谢谢。

4 个答案:

答案 0 :(得分:11)

您似乎正在运行Python 3.x. 有关对csv文件使用二进制模式的建议适用于Python 2.x。 3.x不需要编解码器模块 - 只需在打开文件时使用encoding=whatever 3.x需要的是使用 newline=''打开文件。这适用于阅读和写作,虽然没有记录用于编写(错误报告已提交)。在整理出你的间距问题后,这将有效:

import csv
data = [
    ['\xfforick', 123.456],
    ['polonius', 987.564],
    ]
with open('demo.csv', 'w', newline='', encoding='utf8') as f:
    writer = csv.writer(f)
    for row in data:
        writer.writerow(row)

输出文件的内容:

>>> open('demo.csv', 'rb').read()
b'\xc3\xbforick,123.456\r\npolonius,987.564\r\n'
>>>

建议:考虑一下代码的易读性......而不是

for i in range(self.ui.table.rowCount()):
    rowData = [self.ui.table.item(i,0).text().encode('utf-8')\
    ,self.ui.table.item(i,1).text().encode('utf-8')\
    ,self.ui.table.item(i,2).text().encode('utf-8')\
    ,self.ui.table.item(i,3).text().encode('utf-8')\
    ,self.ui.table.item(i,4).text().encode('utf-8')]
    dataWriter.writerow(rowData)

table = self.ui.table
for i in range(table.rowCount()):
    row = [table.item(i, j).text() for j in range(5)]
    writer.writerow(row)

答案 1 :(得分:1)

在Python 3中,在二进制模式下使用open会创建一个io.BufferedWriter,它需要字节而不是字符串。通过使用encode方法,您可以将字符串更改为字节;但我认为cvs.writer.writerow在写入之前将这些字节转换回字符串。

您应该尝试找出造成双倍间距的原因,而不是以二进制模式打开文件。我有两个问题:

  1. 您使用的是什么平台?

  2. print repr(self.ui.table.item(i,4).text())的输出是什么?

  3. 我的猜测是brandizzi的strip()方法可行,但如果没有,我们需要做一些故障排除。

    编辑:好的,John Machin的帖子清除了所有内容。在Python 3中解决此问题的正确方法是使用newline=''打开文件,该文件禁用自动换行。 This bug report包含一些有用的信息。

答案 2 :(得分:0)

也许你可以让codecs模块为你做Unicode编码,然后尝试这样的事情:

import codecs, csv

with codecs.open(fileName, 'w', encoding = 'utf_8') as f:
    writer = csv.writer(f)
    writer.writerow(['some string', 'some other string'])

答案 3 :(得分:-2)

我并不感到惊讶。如果你要写出一个值为13的字节,模块应该如何判断这是否是二进制字段的一部分,或者是CSV中新记录的开头? CSV文件不适合存储二进制数据。

如果你绝对需要它在那里,你可以看看BASE 64编码......

马丁