forma portátil de escribir un archivo csv en python 2 o python 3
python-3.x python-2.7 (2)
En Windows, encontré una forma compatible con Python 2 y 3 de hacerlo cambiando la opción de csv
lineterminator
(que por defecto es
"/r/n"
que hace que uno sea demasiado cuando el archivo está abierto en modo texto en Windows)
import csv
with open("out.csv","w") as f:
cr = csv.writer(f,delimiter=";",lineterminator="/n")
cr.writerow(["a","b","c"])
cr.writerow(["d","e","f"])
cr.writerow(["a","b","c"])
cr.writerow(["d","e","f"])
Cualquiera sea la versión de Python, eso creará un archivo csv sin las infames "líneas en blanco".
El único inconveniente es que en Linux, este método produciría archivos
/r
-free, que tal vez no sea el estándar (aunque los archivos aún se abren correctamente en Excel, no hay líneas en blanco y aún varias líneas :))
el problema persiste en 3.6.2 (solo me revisé como debería haberlo hecho hace algún tiempo)
En mi cuadro de Windows, generalmente hice esto en python 2 para escribir un archivo csv:
import csv
f = open("out.csv","wb")
cr = csv.writer(f,delimiter='';'')
cr.writerow(["a","b","c"])
f.close()
Ahora que Python 3 prohíbe escribir archivos de texto como binarios, ese código ya no funciona. Eso funciona:
import csv
f = open("out.csv","w",newline='''')
cr = csv.writer(f,delimiter='';'')
cr.writerow(["a","b","c"])
f.close()
El problema es: el parámetro de
newline
es desconocido para Python 2.
Por supuesto, omitir la nueva línea da como resultado un archivo csv con demasiados caracteres, por lo que no es aceptable.
Actualmente estoy realizando un proceso compatible con versiones anteriores para migrar progresivamente de python 2 a python 3.5. Hay muchas de esas declaraciones en todos mis módulos.
Mi solución fue incrustar el código en un módulo personalizado, y el módulo personalizado devuelve el controlador de archivo + objeto de escritura. Se realiza una verificación de la versión de Python dentro del módulo, lo que permite que cualquier módulo que use mi módulo funcione sin importar la versión de Python sin demasiados hacks.
¿Hay una mejor manera?
Para leer y escribir archivos csv, tampoco he encontrado una mejor manera, sin embargo, encapsularía en una función separada como se muestra a continuación. La ventaja es que la lógica está en un solo lugar en lugar de duplicarse si se necesita más de una vez.
import csv
import sys
def open_csv(filename, mode=''r''):
"""Open a csv file in proper mode depending on Python verion."""
return(open(filename, mode=mode+''b'') if sys.version_info[0] == 2 else
open(filename, mode=mode, newline=''''))
with open_csv(''out.csv'', ''w'') as f:
writer = csv.writer(f, delimiter='';'')
writer.writerow([1, 2, 3])
writer.writerow([''a'', ''b'', ''c''])