CSV 模块的编写器不允许我写出二进制文件
我尝试在打开文件时仅使用“w”标签,但它使行间距加倍,导致读取无法正常工作。所以我发现更改为“wb”将是正确的格式。现在我使用“wb”标志,我无法让 csv.writer.writerow() 工作。我已经对所有字符串进行了编码,但不明白为什么我不断收到此错误。我看到的所有问题都说 b'string here' 或 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)
我认为它可以工作,但它仍然给我以下错误: “类型错误:必须是字节或缓冲区,而不是 str” 在“dataWriter.writerow(rowData)”行上。
任何帮助将不胜感激。 谢谢。
I tried to just use the 'w' tag while opening the file, but it double spaced the lines which caused the read to not work. So I found that changing to 'wb' will be the correct formatting. Now that I am using the 'wb' flag I can't get the csv.writer.writerow() to work. I have encoded all my strings and am lost as to why I keep getting this error. All the questions I see say that b'string here' or myString.encode('ascii') solves the error I get, but it is not solving it for me. Here is what I have:
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)
Which I figured would work but it still gives me the following error:
"TypeError: must be bytes or buffer, not str"
on the line "dataWriter.writerow(rowData).
Any help would be apreciated.
Thank you.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
您似乎正在运行 Python 3.x。 关于对 csv 文件使用二进制模式的建议适用于 Python 2.x。3.x 不需要编解码器模块 - 只需在打开时使用
encoding=whatever
文件。 3.x 需要的是使用newline=''
打开文件。这适用于阅读和写作,尽管没有书面记录(错误报告已提交)。解决双倍间距问题后,这将起作用:输出文件的内容:
建议:考虑代码的易读性......而不是
尝试
You appear to be running Python 3.x. Advice about using binary mode for csv files applies to Python 2.x. The codecs module is not required for 3.x -- just use
encoding=whatever
when you open the file. What is needed for 3.x is that the file be opened withnewline=''
. This applies to both reading and writing, although it is not documented for writing (bug report has been submitted). After sorting out your doble-spacing problem, this will work:Contents of output file:
Suggestion: give some consideration to legibility of your code ... instead of
try
在 Python 3 中,在二进制模式下使用
open
会创建一个io.BufferedWriter
,它需要字节,而不是字符串。通过使用encode
方法,您可以将字符串转换为字节;但我认为 cvs.writer.writerow 在写入之前将这些字节转换回字符串。您应该尝试找出导致双倍行距的原因,而不是以二进制模式打开文件。我有两个问题:
您使用什么平台?
print repr(self.ui.table.item(i,4).text()) 的输出是什么?
我的猜测是,brandizzi 的
strip()
方法可以工作,但如果不行,我们需要进行一些故障排除。编辑:好的,John Machin 的帖子澄清了一切。在 Python 3 中解决此问题的正确方法是使用
newline=''
打开文件,这会禁用自动换行符翻译。 此错误报告包含一些有用的信息。In Python 3, using
open
in binary mode creates anio.BufferedWriter
, which wants bytes, not strings. By using theencode
method, you change your strings into bytes; but I thinkcvs.writer.writerow
converts those bytes back into strings before writing.Instead of opening the file in binary mode, you should try to figure out what's causing the double spacing. I have two questions:
What platform are you using?
What is the output of
print repr(self.ui.table.item(i,4).text())
?My guess is that brandizzi's
strip()
method will work, but if not, we'll need to do some troubleshooting.Edit: Ok, John Machin's post clears it all up. The correct way to fix this problem in Python 3 is to open the file with
newline=''
, which disables automatic newline translation. This bug report contains some helpful information.也许您可以让
codecs
模块为您执行 Unicode 编码,然后尝试这样的操作:Maybe you could let the
codecs
module do the Unicode encoding for you, and try something like this instead:我在尝试将 csv 写入 paramiko sftp 文件流时遇到了这个问题,该文件无法在文本模式下打开。
我想出的也适用于OP的解决方案是:
产生正确的输出:
I'm running into this problem trying to write a csv to a paramiko sftp file stream which can't be opened in text mode.
The solution I came up with which would have worked for the OP as well was this:
Produces correct output:
我一点也不感到惊讶。如果您要写出一个值为 13 的字节,模块如何判断这是二进制字段的一部分,还是 CSV 中新记录的开始? CSV 文件不适合存储二进制数据。
如果你绝对需要它在那里,你可以研究 BASE 64 编码......
马丁
I'm hardly surprised. If you were to write out a byte of value 13, how is the module supposed to tell if this is part of a binary field, or the start of a new record in the CSV? CSV files are not suitable for storing binary data.
If you absolutely need it to be in there, you could look into BASE 64 encoding...
Martin