csv.Error: ітератор повинен повертати рядки, а не байти


158

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: ітератор повинен повертати рядки, а не байти (ви відкрили файл у текстовому режимі?)

Як я можу це виправити?

Відповіді:


214

Ви відкриваєте файл у текстовому режимі.

Більш конкретно:

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)

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, і ви застрягли в інтерактивному сеансі з файлом, з яким нічого не можете зробити, ви оцінили б мою пораду ...
Aaron Hall

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.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.