¿Usando el módulo csv para leer texto delimitado por ascii?

Puede o no conocer el texto delimitado por ASCII , que tiene la ventaja de utilizar caracteres que no son del teclado para separar campos y líneas.

Escribir esto es bastante fácil:

import csv with open('ascii_delim.adt', 'w') as f: writer = csv.writer(f, delimiter=chr(31), lineterminator=chr(30)) writer.writerow(('Sir Lancelot of Camelot', 'To seek the Holy Grail', 'blue')) writer.writerow(('Sir Galahad of Camelot', 'I seek the Grail', 'blue... no yellow!')) 

Y, efectivamente, consigues que las cosas se desechen adecuadamente. Sin embargo, al leer, lineterminator no hace nada, y si bash hacer:

 open('ascii_delim.adt', newline=chr(30)) 

ValueError: illegal newline value: un ValueError: illegal newline value:

Entonces, ¿cómo puedo leer en mi archivo delimitado por ASCII? ¿Estoy relegado a hacer line.split(chr(30)) ?

Puede hacerlo traduciendo efectivamente los caracteres de fin de línea en el archivo a los caracteres de nueva línea que csv.reader está codificado para reconocer:

 import csv with open('ascii_delim.adt', 'w') as f: writer = csv.writer(f, delimiter=chr(31), lineterminator=chr(30)) writer.writerow(('Sir Lancelot of Camelot', 'To seek the Holy Grail', 'blue')) writer.writerow(('Sir Galahad of Camelot', 'I seek the Grail', 'blue... no yellow!')) def readlines(f, newline='\n'): while True: line = [] while True: ch = f.read(1) if ch == '': # end of file? return elif ch == newline: # end of line? line.append('\n') break line.append(ch) yield ''.join(line) with open('ascii_delim.adt', 'rb') as f: reader = csv.reader(readlines(f, newline=chr(30)), delimiter=chr(31)) for row in reader: print row 

Salida:

 ['Sir Lancelot of Camelot', 'To seek the Holy Grail', 'blue'] ['Sir Galahad of Camelot', 'I seek the Grail', 'blue... no yellow!'] 

La documentación dice:

El lector está codificado para reconocer ‘\ r’ o ‘\ n’ como final de línea, e ignora el determinador de línea. Este comportamiento puede cambiar en el futuro.

Por lo tanto, el módulo csv no puede leer archivos CSV que usan terminadores de línea personalizados.

Hey, estuve luchando con un problema similar todo el día. Escribí una función muy inspirada en @martineau que debería resolverla por ti. Mi función es más lenta pero puede analizar archivos delimitados por cualquier tipo de cadena. ¡Espero eso ayude!

 import csv def custom_CSV_reader(csv_file,row_delimiter,col_delimiter): with open(csv_file, 'rb') as f: row = []; result = []; temp_row = '' temp_col = '' line = '' go = 1; while go == 1: while go == 1: ch = f.read(1) if ch == '': # end of file? go = 0 if ch != '\n' and ch != '\t' and ch != ',': temp_row = temp_row + ch temp_col = temp_col + ch line = line + ch if row_delimiter in temp_row: line = line[:-len(row_delimiter)] row.append(line) temp_row = '' line= '' break elif col_delimiter in temp_col: line = line[:-len(col_delimiter)] row.append(line) result.append(row) row = []; temp_col = '' line = '' break return result 

Por los documentos para open :

nueva línea controla cómo funciona el modo de nuevas líneas universal (solo se aplica al modo de texto). Puede ser None , '' , '\n' , '\r' y '\r\n' .

así que open no manejará tu archivo. Por los documentos csv :

Nota El reader está codificado para reconocer a '\r' o '\n' como final de línea, e ignora lineterminator .

así que eso tampoco lo hará. También examiné si str.splitlines era configurable, pero usa un conjunto definido de límites.

¿Estoy relegado a hacer line.split(chr(30)) ?

Parece de esa manera, lo siento!