csv.Error: 迭代器应该返回字符串而不是字节。

202

示例.csv 包含以下内容:

NAME    Id   No  Dept
Tom     1    12   CS
Hendry  2    35   EC
Bahamas 3    21   IT
Frank   4    61   EE

而Python文件包含以下代码:

import csv
ifile  = open('sample.csv', "rb")
read = csv.reader(ifile)
for row in read :
    print (row) 

当我在Python中运行上述代码时,出现以下异常:

File "csvformat.py", line 4, in for row in read : _csv.Error: iterator should return strings, not bytes (did you open the file in text mode?)

如何解决这个问题?

6个回答

250

您以文本模式打开了该文件。

更具体地说:

ifile  = open('sample.csv', "rt", encoding=<theencodingofthefile>)

使用"ascii" 和 "utf8"是好的编码推测。您也可以省略编码,它将使用系统默认编码,通常为UTF8,但可能是其他内容。


5
补充一下,如果你尝试从/向CSV文件读取/写入时出现编码错误,添加特定的编码可以有所帮助。我刚刚通过添加 "encoding ='utf-8'" 来修复了我的错误。 - covfefe

119

它抛出异常的原因是您使用了参数rb,这将以二进制模式打开文件。将其更改为r,它将默认以文本模式打开文件。

您的代码:

import csv
ifile  = open('sample.csv', "rb")
read = csv.reader(ifile)
for row in read :
    print (row) 

新代码:

import csv
ifile  = open('sample.csv', "r")
read = csv.reader(ifile)
for row in read :
    print (row)

将参数rb更改为r完美解决了我的问题。非常感谢! - Birasafab

50
在Python3中,csv.reader期望传递的可迭代对象返回字符串而不是字节。这里有另一种解决此问题的方法,它使用codecs模块:
import csv
import codecs
ifile  = open('sample.csv', "rb")
read = csv.reader(codecs.iterdecode(ifile, 'utf-8'))
for row in read :
    print (row) 

4
请注意,该选项并非最安全的选项。如果可以使用TextIOWrapper,则应该使用。问题描述: iterdecode会吞噬空字符串 iterdecode在处理多字节字符时不安全解决方法: 在csv流上使用TextIOWrapper - kavdev
1
谢谢!我在 Python3 上遇到了这个问题。 - Kenny Aires
2
@Grigoriy Mikhalkin,我对你的编解码方案表示钦佩,它成功解决了一个问题:在S3中存储的CSV文件流无法被csv.reader识别,而有了编解码方案后就可以顺利读取了。 - dimButTries

33

你的问题在于你的打开标志 open 中有一个 b。标志 rt(读取文本)是默认设置,所以使用上下文管理器,只需执行以下操作:

with open('sample.csv') as ifile:
    read = csv.reader(ifile) 
    for row in read:
        print (row)  

上下文管理器是指您不需要通用的错误处理(否则您可能会在文件打开时陷入困境,特别是在解释器中),因为它将在出现错误或退出上下文时自动关闭文件。

上述与以下内容相同:

with open('sample.csv', 'r') as ifile:
    ...
with open('sample.csv', 'rt') as ifile:
    ...

“with”语句,也称为上下文管理器,与此问题完全无关! - RayLuo
5
当我演示文件处理时,我也会展示最佳实践。我经常这样做。如果你是 Python 新手,并且在交互式会话中遇到无法处理的文件,你会感激我的建议... - Russia Must Remove Putin

11

运行一个老的Python脚本(使用Python 2.6.4开发时)时,我遇到了这个错误。

更新到3.6.2后,为了解决CSV读取错误,我不得不从open调用中删除所有“rb”参数。


2

这是 Django 中的一个意外情况。根据我所知,filefield 所带的 open 总是以 byte 模式打开文件。你需要用 Python 的 open 替代。

因此,如果 avccont_datafile 是一个具有一个名为 datafile 的字段的模型实例,则以下代码....

with avccount_datafile.datafile.file.open('rt') as fp:
    self.avc_data = csv.DictReader(fp)

出现错误

_csv.Error: iterator should return strings, not bytes (did you open the file in text mode?)

但这样修复了它

filename = avccount_datafile.datafile.file.name
with open(filename, 'rt') as fp:
        self.avc_data = csv.DictReader(fp)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接