EDIT: Je l'ai mis dans le titre, mais je viens de réaliser que je ne l'ai pas mentionné dans le corps. Cela semble être spécifique à Windows.
J'ai du mal à écrire une sortie en utilisant le module csv
Python dans un script qui fonctionne avec les deux Python 2.7 et 3.3.
Essayez d'abord ce qui fonctionne comme prévu dans Python 2.7:
with open('test.csv', 'wb') as csv_file:
writer = csv.DictWriter(csv_file, ['header1', 'header2'])
writer.writeheader()
for item in items:
writer.writerow(item)
Cependant, lorsque cette même chose est exécutée dans Python 3.3 vous vous retrouvez avec:
TypeError: 'str' does not support the buffer interface
Je change donc 'wb'
à 'wt'
et il s'exécute, mais maintenant j'ai une ligne vierge supplémentaire toutes les deux lignes du fichier.
Pour corriger cela, je change:
with open('test.csv', 'wt') as csv_file:
à:
with open('test.csv', 'wt', newline='') as csv_file:
Mais maintenant, ça casse Python 2.7:
TypeError: 'newline' is an invalid keyword argument for this function
Je sais que je pourrais simplement faire quelque chose comme:
try:
with open('test.csv', 'wt', newline='') as csv_file:
writer = csv.DictWriter(csv_file, ['header1', 'header2'])
writer.writeheader()
for item in items:
writer.writerow(item)
except TypeError:
with open('test.csv', 'wb') as csv_file:
writer = csv.DictWriter(csv_file, ['header1', 'header2'])
writer.writeheader()
for item in items:
writer.writerow(item)
Cependant, cela a une duplication sérieusement mauvaise.
Quelqu'un at-il une façon plus propre de le faire?
EDIT: Les données de test sont simples et n'ont pas de nouvelles lignes ou quoi que ce soit:
items = [{'header1': 'value', 'header2': 'value2'},
{'header1': 'blah1', 'header2': 'blah2'}]
J'ai essayé plusieurs façons. Pour autant que je sache, simple en utilisant 'w'
pourrait être une solution:
with open('test.csv', 'w') as csv_file:
writer = csv.DictWriter(csv_file, fieldnames=['header1', 'header2'], lineterminator='\n')
# write something
Voici un moyen générique plus simple:
import sys
if sys.version_info[0] == 2: # Not named on 2.6
access = 'wb'
kwargs = {}
else:
access = 'wt'
kwargs = {'newline':''}
with open('test.csv', access, **kwargs) as csv_file:
writer = csv.DictWriter(csv_file, ['header1', 'header2'])
writer.writeheader()
for item in items:
writer.writerow(item)
Le principe ici n'est pas d'essayer de combattre les différences entre Python 2 et 3 mais d'avoir du code conditionnel. Vous ne pouvez aller jusque-là en écrivant du code sans ce genre de test, tôt ou tard vous devra tester la version Python.