exportar - leer csv python
¿Cómo leer un archivo CSV de una secuencia y procesar cada línea tal como está escrita? (3)
Como dice en la documentación ,
Para hacer que un bucle
for
la forma más eficiente de recorrer las líneas de un archivo (una operación muy común), el métodonext()
usa un búfer de lectura anticipada oculto.
Y puede ver mirando la implementación del módulo csv
(línea 784) que csv.reader
llama al método next()
del iterador subyacente (a través de PyIter_Next
).
Por lo tanto, si realmente desea la lectura sin búfer de archivos CSV, debe convertir el objeto de archivo (aquí sys.stdin
) en un iterador cuyo método next()
realidad llama a readline()
lugar. Esto puede hacerse fácilmente usando la forma de dos argumentos de la función iter
. Así que cambie el código en test_reader.py
a algo como esto:
for row in csv.reader(iter(sys.stdin.readline, '''')):
print("Read: ({}) {!r}".format(time.time(), row))
Por ejemplo,
$ python test_writer.py | python test_reader.py
Read: (1388776652.964925) [''R0'', ''$'']
Read: (1388776653.466134) [''R1'', ''$$'']
Read: (1388776653.967327) [''R2'', ''$$$'']
Read: (1388776654.468532) [''R3'', ''$$$$'']
[etc]
¿Puedes explicar por qué necesitas lectura sin búfer de archivos CSV? Puede haber una mejor solución para lo que sea que estés tratando de hacer.
Me gustaría leer un archivo CSV de la entrada estándar y procesar cada fila como viene. Mi código de salida CSV escribe filas una por una, pero mi lector espera a que termine la secuencia antes de iterar las filas. ¿Es esto una limitación del módulo csv
? ¿Estoy haciendo algo mal?
Mi código de lector:
import csv
import sys
import time
reader = csv.reader(sys.stdin)
for row in reader:
print "Read: (%s) %r" % (time.time(), row)
Mi código de escritor:
import csv
import sys
import time
writer = csv.writer(sys.stdout)
for i in range(8):
writer.writerow(["R%d" % i, "$" * (i+1)])
sys.stdout.flush()
time.sleep(0.5)
Salida de python test_writer.py | python test_reader.py
python test_writer.py | python test_reader.py
:
Read: (1309597426.3) [''R0'', ''$'']
Read: (1309597426.3) [''R1'', ''$$'']
Read: (1309597426.3) [''R2'', ''$$$'']
Read: (1309597426.3) [''R3'', ''$$$$'']
Read: (1309597426.3) [''R4'', ''$$$$$'']
Read: (1309597426.3) [''R5'', ''$$$$$$'']
Read: (1309597426.3) [''R6'', ''$$$$$$$'']
Read: (1309597426.3) [''R7'', ''$$$$$$$$'']
Como puede ver, todas las instrucciones de impresión se ejecutan al mismo tiempo, pero espero que haya una brecha de 500 ms.
Estás descargando stdout, pero no stdin.
Sys.stdin
también tiene un método flush()
, intente usarlo después de cada línea leída si realmente desea deshabilitar el almacenamiento en búfer.
Tal vez es una limitación. Lea esto http://docs.python.org/using/cmdline.html#cmdoption-unittest-discover-u
Tenga en cuenta que hay un búfer interno en file.readlines () y File Objects (para la línea en sys.stdin) que no está influenciado por esta opción. Para solucionar esto, querrás usar file.readline () dentro de un while 1: loop.
Modifiqué test_reader.py de la siguiente manera:
import csv, sys, time
while True:
print "Read: (%s) %r" % (time.time(), sys.stdin.readline())
Salida
python test_writer.py | python test_reader.py
Read: (1309600865.84) ''R0,$/r/n''
Read: (1309600865.84) ''R1,$$/r/n''
Read: (1309600866.34) ''R2,$$$/r/n''
Read: (1309600866.84) ''R3,$$$$/r/n''
Read: (1309600867.34) ''R4,$$$$$/r/n''
Read: (1309600867.84) ''R5,$$$$$$/r/n''
Read: (1309600868.34) ''R6,$$$$$$$/r/n''
Read: (1309600868.84) ''R7,$$$$$$$$/r/n''