CSV模块的编写器不允许我写出二进制

xdyibdwo  于 2023-05-26  发布在  其他
关注(0)|答案(5)|浏览(134)

我试图在打开文件时只使用“w”标签,但它使行间隔加倍,导致读取不起作用。因此,我发现更改为'wb'将是正确的格式。现在我使用的是'wb'标志,我不能让csv.writer.writerow()工作。我已经编码了我所有的字符串,我不知道为什么我一直得到这个错误。我看到的所有问题都说b 'stringhere'或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)

我认为它可以工作,但它仍然给我以下错误:“类型错误:必须是bytes或buffer,而不是str”on the line“dataWriter.writerrow(rowData).
任何帮助都将不胜感激。谢谢你。

dl5txlt9

dl5txlt91#

您似乎正在运行Python 3.x。* 关于对csv文件使用二进制模式的建议适用于Python 2.x。* codecs模块在Python 3.x中不是必需的--打开文件时使用encoding=whatever即可。* 3.x需要的是用 * newline=''打开文件。这适用于阅读和写入,尽管没有记录写入(bug报告已提交)。在解决了你的双间距问题后,这将起作用:

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)
im9ewurl

im9ewurl2#

在Python 3中,在二进制模式下使用open创建了一个io.BufferedWriter,它需要字节,而不是字符串。通过使用encode方法,可以将字符串转换为字节;但我认为cvs.writer.writerow在写入之前将这些字节转换回字符串。
而不是打开文件在二进制模式下,你应该尝试找出是什么原因造成的双空格。我有两个问题:
1.您使用的是什么平台?

  1. print repr(self.ui.table.item(i,4).text())的输出是什么?
    我的猜测是brandizzi的strip()方法会起作用,但如果不行,我们就需要做一些故障排除。

编辑:好的,约翰·梅钦的文章把一切都弄清楚了。在Python 3中解决这个问题的正确方法是使用newline=''打开文件,这将禁用自动换行转换。This bug report包含一些有用的信息。

wsewodh2

wsewodh23#

也许你可以让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'])
ibps3vxo

ibps3vxo4#

我遇到了这个问题,试图写一个csv到一个paramiko sftp文件流,不能在文本模式下打开。
我提出的解决方案也适用于OP,是这样的:

import codecs, csv, io
buf = io.BytesIO()
StreamWriter = codecs.getwriter( 'utf-8' )
w = csv.writer( StreamWriter( buf ))
w.writerow([ 'foo', 'bar' ])
w.writerow([ 'bar', 'foo' ])
print( repr( buf.getvalue() ))

产生正确的输出:

b'foo,bar\r\nbar,foo\r\n'
syqv5f0l

syqv5f0l5#

我一点也不惊讶如果你要写出一个值为13的字节,模块应该如何判断这是二进制字段的一部分,还是CSV中新记录的开始?CSV文件不适合存储二进制数据。
如果你绝对需要它在那里,你可以看看base64编码...
马丁

相关问题