csv.Error: iterator harus mengembalikan string, bukan byte

159

Sample.csv berisi yang berikut:

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

Dan file Python berisi kode berikut:

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

Ketika saya menjalankan kode di atas dengan Python, saya mendapatkan pengecualian berikut:

File "csvformat.py", baris 4, dalam untuk baris di baca: _csv.Error: iterator harus mengembalikan string, bukan byte (apakah Anda membuka file dalam mode teks?)

Bagaimana saya bisa memperbaikinya?

Pika sang Penyihir Paus
sumber

Jawaban:

215

Anda membuka file dalam mode teks.

Lebih spesifik:

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

Tebakan yang bagus untuk penyandian adalah "ascii" dan "utf8". Anda juga dapat menonaktifkan pengodean, dan itu akan menggunakan pengodean default sistem, yang cenderung UTF8, tetapi mungkin sesuatu yang lain.

Lennart Regebro
sumber
4
Hanya ingin menambahkan ini bahwa jika Anda mendapatkan kesalahan penyandian ketika Anda mencoba membaca / menulis dari / ke file CSV, menambahkan penyandian tertentu dapat membantu. Saya baru saja memperbaiki bug ini pada saya dengan menambahkan "encoding = 'utf-8'".
covfefe
96

Saya baru saja memperbaiki masalah ini dengan kode saya. Alasannya melemparkan pengecualian itu adalah karena Anda memiliki argumen rb. Ubah itu menjadi r.

Kode Anda:

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

Kode baru:

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

Masalah Anda adalah Anda memiliki bdi openbendera. Bendera rt(baca, teks) adalah default, jadi, menggunakan manajer konteks, cukup lakukan ini:

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

Manajer konteks berarti Anda tidak memerlukan penanganan kesalahan umum (yang tanpanya Anda mungkin akan terjebak dengan file yang terbuka, terutama dalam juru bahasa), karena itu akan secara otomatis menutup file pada kesalahan, atau keluar dari konteks.

Di atas sama dengan:

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

atau

with open('sample.csv', 'rt') as ifile:
    ...
Aaron Hall
sumber
The withpernyataan alias manajer konteks tidak ada hubungannya dengan pertanyaan ini, sama sekali!
RayLuo
4
@ RayLuo Ketika saya menunjukkan penanganan file, saya juga akan menunjukkan praktik terbaik di sekitarnya. Saya melakukannya dengan cukup konsisten. Jika Anda baru mengenal Python, dan Anda terjebak dalam sesi interaktif dengan file yang tidak dapat Anda lakukan apa pun, Anda akan menghargai saran saya ...
Aaron Hall
24

Dalam Python3, csv.readermengharapkan, yang lulus mengembalikan string, bukan byte. Berikut adalah satu lagi solusi untuk masalah ini, yang menggunakan codecsmodul:

import csv
import codecs
ifile  = open('sample.csv', "rb")
read = csv.reader(codecs.iterdecode(ifile, 'utf-8'))
for row in read :
    print (row) 
Grigoriy Mikhalkin
sumber
3
Perhatikan bahwa opsi ini bukan yang paling aman. Jika Anda dapat menggunakan TextIOWrapper, Anda harus melakukannya. Deskripsi masalah: iterdecode makan string kosong iterdecode tidak aman dengan karakter multi-byte Solusi: TextIOWrapper pada aliran csv
kavdev
1
Terima kasih! menghadapi masalah ini di Python3.
Kenny Aires
9

Saya mengalami kesalahan ini saat menjalankan skrip python lama yang dikembangkan dengan Python 2.6.4

Ketika memperbarui ke 3.6.2, saya harus menghapus semua parameter 'rb' dari panggilan terbuka untuk memperbaiki kesalahan membaca csv ini.

Michael Fayad
sumber