csv.Error: l'itérateur doit renvoyer des chaînes, pas des octets

159

Sample.csv contient les éléments suivants:

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

Et le fichier Python contient le code suivant:

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

Lorsque j'exécute le code ci-dessus en Python, j'obtiens l'exception suivante:

Fichier "csvformat.py", ligne 4, dans pour ligne en lecture: _csv.Erreur: l'itérateur doit renvoyer des chaînes, pas des octets (avez-vous ouvert le fichier en mode texte?)

Comment puis-je y remédier?

Pika le magicien des baleines
la source

Réponses:

215

Vous ouvrez le fichier en mode texte.

Plus précisement:

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

Les bonnes suppositions pour l'encodage sont "ascii" et "utf8". Vous pouvez également laisser l'encodage désactivé, et il utilisera l'encodage par défaut du système, qui a tendance à être UTF8, mais peut être autre chose.

Lennart Regebro
la source
4
Je veux juste ajouter à cela que si vous obtenez des erreurs d'encodage lorsque vous essayez de lire / écrire depuis / vers un fichier CSV, l'ajout d'un encodage particulier peut vous aider. Je viens de corriger ce bug sur le mien en ajoutant "encoding = 'utf-8'".
covfefe
96

Je viens de résoudre ce problème avec mon code. La raison pour laquelle il lève cette exception est que vous avez l'argument rb. Changez cela en r.

Votre code:

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

Nouveau code:

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

Votre problème est que vous avez le bdans le opendrapeau. Le drapeau rt(lecture, texte) est la valeur par défaut, donc, en utilisant le gestionnaire de contexte, faites simplement ceci:

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

Le gestionnaire de contexte signifie que vous n'avez pas besoin de gestion générique des erreurs (sans quoi vous risquez de rester bloqué avec le fichier ouvert, en particulier dans un interpréteur), car il fermera automatiquement le fichier en cas d'erreur ou en quittant le contexte.

Ce qui précède est le même que:

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

ou

with open('sample.csv', 'rt') as ifile:
    ...
Salle Aaron
la source
La withdéclaration aka le gestionnaire de contexte n'a rien à voir avec cette question, du tout!
RayLuo
4
@RayLuo Lorsque je fais la démonstration de la gestion de fichiers, je vais également montrer les meilleures pratiques autour de cela. Je fais cela assez régulièrement. Si vous êtes nouveau sur Python et que vous êtes coincé dans une session interactive avec un fichier avec lequel vous ne pouvez rien faire, vous auriez apprécié mon conseil ...
Aaron Hall
24

En Python3, csv.readerattend, qui passé iterable renvoie des chaînes, pas des octets. Voici une autre solution à ce problème, qui utilise le codecsmodule:

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
la source
3
Notez que cette option n'est pas la plus sûre. Si vous pouvez utiliser TextIOWrapper, vous devriez. Description des problèmes: iterdecode mange des chaînes vides iterdecode n'est pas sûr avec des caractères multi-octets La solution: TextIOWrapper sur un flux csv
kavdev
1
Merci! faisait face à ce problème sur Python3.
Kenny Aires
9

J'ai eu cette erreur lors de l'exécution d'un ancien script python développé avec Python 2.6.4

Lors de la mise à jour vers 3.6.2, j'ai dû supprimer tous les paramètres 'rb' des appels ouverts afin de corriger cette erreur de lecture csv.

Michael Fayad
la source