web-dev-qa-db-fra.com

Python 2 Le script CSV produit un terminateur de ligne incorrect sous Windows

Selon le sa documentation csv.writer devrait utiliser '\ r\n' comme lineterminator par défaut.

import csv

with open("test.csv", "w") as f:
    writer = csv.writer(f)

    rows = [(0,1,2,3,4),
           (-0,-1,-2,-3,-4),
           ("a","b","c","d","e"),
           ("A","B","C","D","E")]           

    print writer.dialect.lineterminator.replace("\r", "\\r").replace("\n", "\\n")
    writer.writerows(rows)
    print writer.dialect.lineterminator.replace("\r", "\\r").replace("\n", "\\n")

Ceci imprime

\r\n
\r\n

comme prévu. Mais, le fichier csv créé utilise le lineterminator '\ r\r\n'

0,1,2,3,4

0,-1,-2,-3,-4

a,b,c,d,e

A,B,C,D,E

Est-ce un bug ou y a-t-il quelque chose qui ne va pas dans mon utilisation de csv.writer?

Version Python:

ActivePython 2.6.2.2 (ActiveState Software Inc.) basé sur Python 2.6.2 (r262: 71600, 21 avril 2009, 15:05:37) [MSC v.1500 32 bits (Intel) ] sur win32

sur Windows Vista

43
wierob

En Python 2.x, ouvrez toujours votre fichier en mode binaire , comme indiqué. csv écrit \r\n comme vous vous y attendiez, mais le mécanisme de fichier texte Windows sous-jacent se coupe et modifie \n à \r\n ... effet total: \r\r\n

Du csv.writer documentation:

Si csvfile est un objet fichier, il doit être ouvert avec le 'b' flag sur les plateformes où cela fait une différence.

Il semble y avoir une certaine réticence à prononcer le nom du principal coupable :-)

Edit: Comme mentionné par @jebob dans les commentaires de cette réponse et basé sur @Dave Burton answer , pour gérer ce cas dans les deux Python 2 et 3, vous devriez procédez comme suit:

if sys.version_info >= (3,0,0):
    f = open(filename, 'w', newline='')
else:
    f = open(filename, 'wb')
65
John Machin

Malheureusement, c'est un peu différent avec le module csv pour Python 3, mais ce code fonctionnera à la fois sur Python 2 et Python 3:

if sys.version_info >= (3,0,0):
    f = open(filename, 'w', newline='')
else:
    f = open(filename, 'wb')
25
Dave Burton

Pour changer le terminateur de ligne dans Python 2.7 csv writer use

writer = csv.writer(f, delimiter = '|', lineterminator='\n')

Il s'agit d'un moyen beaucoup plus simple de changer le délimiteur par défaut de\r\n.

23
Jason Callahan