CSV en Python ajoutant un retour de chariot supplémentaire, sur Windows

en Python 2.7 tournant sous Windows XP pro:

import csv
outfile = file('test.csv', 'w')
writer = csv.writer(outfile, delimiter=',', quoting=csv.QUOTE_MINIMAL)
writer.writerow(['hi','dude'])
writer.writerow(['hi2','dude2'])
outfile.close()

il génère un fichier, test.csv, avec un r supplémentaire à chaque ligne, comme ceci:

test.csv

hi,duderrnhi2,dude2rrn

au lieu des " 151940920 attendus ""

hi,dudernhi2,dude2rn

pourquoi cela se produit-il, ou est-ce réellement le comportement désiré?

157
demandé sur smci 2010-07-07 06:34:25

7 réponses

sous Windows, Ouvrez toujours vos fichiers en mode binaire ("rb "ou" wb") avant de les passer à csv.lecteur ou csv.écrivain.

CSV est vraiment un binaire , avec des "\r\n" séparant les enregistrements. Si le séparateur est écrit en mode texte, l'exécution Python remplace le "\n" par "\r\n" "\r\r\n" que vous avez observé dans votre fichier.

voir cette réponse précédente .


cette réponse a été postée en 2010 et ne règle pas le problème en Python3.

L'un des correctifs possibles en Python3, comme décrit dans la réponse de @YiboYang, est d'ouvrir le fichier avec le paramètre newline défini pour être une chaîne vide:

f = open(path_to_file, 'w', newline='')
writer = csv.writer(f)
...
...
202
répondu John Machin 2018-01-01 17:31:51

alors que @john-machin donne une bonne réponse, ce n'est pas toujours la meilleure approche. Par exemple, il ne fonctionne pas sur Python 3 à moins que vous encodiez toutes vos entrées pour L'auteur CSV. De plus, il n'aborde pas le problème si le script veut utiliser sys.stdout comme le ruisseau.

je suggère plutôt de définir l'attribut 'lineterminator' lors de la création de l'écrivain:

import csv
import sys

doc = csv.writer(sys.stdout, lineterminator='\n')
doc.writerow('abc')
doc.writerow(range(3))

cet exemple fonctionnera sur Python 2 et Python 3 et ne produira pas les indésirables caractères de saut de ligne. Notez cependant qu'il peut produire des lignes nouvelles indésirables (en omettant le caractère LF sur les systèmes D'exploitation Unix).

dans la plupart des cas, cependant, je crois que le comportement est préférable et plus naturel que de traiter tous les CSV comme un format binaire. Je soumets cette réponse comme solution de rechange à votre considération.

204
répondu Jason R. Coombs 2018-09-19 16:20:47

en Python 3( Je n'ai pas essayé en Python 2), Vous pouvez aussi simplement faire

with open('output.csv','w',newline='') as f:
    writer=csv.writer(f)
    writer.writerow(mystuff)
    ...

selon documentation .

pour en savoir plus, voir la note de bas de page du doc."

Si newline=" n'est pas spécifié, les retours à la ligne sont intégrées à l'intérieur cité champs ne sera pas correctement interprété, et sur les plateformes qui utilisent \r\n linendings à écrire un extra \r sera ajouté. Il doit toujours être sûr de spécifier newline=", puisque le module csv fait son propre (universel) de saut de ligne à la manipulation.

43
répondu Yibo Yang 2016-09-08 19:38:57

Je ne sais pas exactement pourquoi cela se produit, mais changer votre mode de fichier de" w "à" wb " le corrige. Voir ma réponse à " comment supprimer ^m " pour plus de détails.

4
répondu Ned Batchelder 2017-05-23 12:18:00

vous devez ajouter l'attribut newline= "\n "pour ouvrir la fonction comme ceci:

with open('file.csv','w',newline="\n") as out:
    csv_out = csv.writer(out, delimiter =';')
3
répondu Gregor Ažbe 2017-06-01 20:41:48

vous pouvez introduire le paramètre lineterminator='\n' dans la commande csv writer.

import csv
delimiter='\t'
with open('tmp.csv', '+w', encoding='utf-8') as stream:
    writer = csv.writer(stream, delimiter=delimiter, quoting=csv.QUOTE_NONE, quotechar='',  lineterminator='\n')
    writer.writerow(['A1' , 'B1', 'C1'])
    writer.writerow(['A2' , 'B2', 'C2'])
    writer.writerow(['A3' , 'B3', 'C3'])
0
répondu Wesam Na 2017-10-09 10:21:54

notez que si vous utilisez DictWriter, vous aurez une nouvelle ligne à partir de la fonction Ouvrir et une nouvelle ligne à partir de la fonction writerow. Vous pouvez utiliser newline=" dans la fonction Ouvrir pour supprimer la nouvelle ligne supplémentaire.

0
répondu Erick Stone 2017-10-23 21:39:33