csv.Error: o iterador deve retornar cadeias, não bytes

159

Sample.csv contém o seguinte:

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

E o arquivo Python contém o seguinte código:

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

Quando executo o código acima em Python, recebo a seguinte exceção:

O arquivo "csvformat.py", linha 4, na linha da leitura: _csv.Error: o iterador deve retornar cadeias, não bytes (você abriu o arquivo no modo de texto?)

Como posso corrigir isso?

Pika, o Mago das Baleias
fonte

Respostas:

215

Você abre o arquivo no modo de texto.

Mais especificamente:

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

Boas suposições para codificação são "ascii" e "utf8". Você também pode deixar a codificação desativada e ela usará a codificação padrão do sistema, que tende a ser UTF8, mas pode ser outra coisa.

Lennart Regebro
fonte
4
Só quero acrescentar a isso que, se você receber erros de codificação ao tentar ler / gravar de / para um arquivo CSV, adicionar uma codificação específica pode ajudar. Eu apenas consertei esse bug adicionando "encoding = 'utf-8'".
Covfefe 16/10/2015
96

Eu apenas corrigi esse problema com o meu código. O motivo pelo qual está lançando essa exceção é porque você tem o argumento rb. Mude isso para r.

Seu código:

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

Novo Código:

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

Seu problema é que você tem bo opensinalizador. A sinalização rt(leitura, texto) é o padrão; portanto, usando o gerenciador de contexto, basta fazer o seguinte:

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

O gerenciador de contexto significa que você não precisa de tratamento genérico de erros (sem o qual pode ficar preso com o arquivo aberto, especialmente em um intérprete), porque ele fechará automaticamente o arquivo em caso de erro ou sair do contexto.

O acima é o mesmo que:

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

ou

with open('sample.csv', 'rt') as ifile:
    ...
Aaron Hall
fonte
A withafirmação aka gerente de contexto não tem nada a ver com essa pergunta!
RayLuo 9/03/19
4
@RayLuo Ao demonstrar o manuseio de arquivos, também demonstrarei as práticas recomendadas. Eu faço isso de forma bastante consistente. Se você é novo para Python, e você ficar preso em uma sessão interativa com um arquivo que você não pode fazer nada com, você teria apreciado o meu conselho ...
Aaron Hall
24

No Python3, csv.readerespera-se, que tenha passado iterável retorna strings, não bytes. Aqui está mais uma solução para esse problema, que usa o codecsmódulo:

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
fonte
3
Observe que essa opção não é a mais segura. Se você pode usar o TextIOWrapper, deve. Descrições Temáticas: iterdecode come cadeias vazias iterdecode não é seguro com caracteres multi-byte a solução: TextIOWrapper em um córrego CSV
kavdev
1
Obrigado! estava enfrentando esse problema no Python3.
Kenny Aires
9

Eu tive esse erro ao executar um script python antigo desenvolvido com o Python 2.6.4

Ao atualizar para a 3.6.2, tive que remover todos os parâmetros 'rb' das chamadas em aberto para corrigir esse erro de leitura do csv.

Michael Fayad
fonte