csv.Error: итератор должен возвращать строки, а не байты

159

Sample.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, я получаю следующее исключение:

Файл "csvformat.py", строка 4, в строке для чтения: _csv.Error: итератор должен возвращать строки, а не байты (вы открывали файл в текстовом режиме?)

Как я могу это исправить?

Пика Волшебник китов
источник

Ответы:

215

Вы открываете файл в текстовом режиме.

Более конкретно:

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

Хорошие догадки для кодирования это "ascii" и "utf8". Вы также можете оставить кодировку выключенной, и она будет использовать системную кодировку по умолчанию, которая имеет тенденцию быть UTF8, но может быть чем-то другим.

Леннарт Регебро
источник
4
Просто хочу добавить к этому, что если вы получаете ошибки кодирования при попытке чтения / записи из / в файл CSV, может помочь добавление определенной кодировки. Я только исправил эту ошибку, добавив "encoding = 'utf-8'".
covfefe
96

Я только что исправил эту проблему с моим кодом. Причина, по которой это исключение, в том, что у вас есть аргумент 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)
MMM
источник
29

Ваша проблема у вас есть bв openфлаге. Флаг 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
4
@RayLuo Когда я демонстрирую обработку файлов, я также собираюсь продемонстрировать лучшие практики вокруг этого. Я делаю это довольно последовательно. Если вы новичок в Python и застряли в интерактивном сеансе с файлом, с которым ничего не можете поделать, вы бы оценили мой совет ...
Аарон Холл
24

В 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) 
Григорий Михалкин
источник
3
Обратите внимание, что этот вариант не самый безопасный. Если вы можете использовать TextIOWrapper, вы должны. Описание проблемы : iterdecode ест пустые строки. Iterdecode не безопасен с многобайтовыми символами . Решение: TextIOWrapper в потоке csv
kavdev
1
Спасибо! столкнулся с этой проблемой на Python3.
Кенни Айрес
9

У меня была эта ошибка при запуске старого скрипта Python, разработанного с Python 2.6.4

При обновлении до 3.6.2 мне пришлось удалить все параметры 'rb' из открытых вызовов, чтобы исправить эту ошибку чтения csv.

Майкл Файяд
источник