如何从流中读取CSV文件并在写入每一行时对其进行处理?

发布于 2021-01-29 17:49:24

我想从标准输入中读取CSV文件,并处理每一行。我的CSV输出代码逐行写入行,但是我的阅读器在迭代行之前等待流终止。这是csv模块的限制吗?难道我做错了什么?

我的读者代码:

import csv
import sys
import time


reader = csv.reader(sys.stdin)
for row in reader:
    print "Read: (%s) %r" % (time.time(), row)

我的作者代码:

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)

输出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', '$$$$$$$$']

如您所见,所有打印语句都在同一时间执行,但是我希望会有500ms的间隔。

关注者
0
被浏览
137
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

    文档中所述

    为了使for循环成为遍历文件行的最有效方法(一种非常常见的操作),该next()方法使用了隐藏的预读缓冲区。

    您可以查看调用底层迭代器方法(via
    csv模块的实现(784行)。csv.reader``next()``PyIter_Next

    因此,如果您真的想无缓冲地读取CSV文件,则需要将文件对象(此处为sys.stdin)转换为next()实际调用其方法的迭代器readline()。使用iter函数的两个参数形式可以轻松完成此操作。因此,将代码更改为test_reader.py如下所示:

    for row in csv.reader(iter(sys.stdin.readline, '')):
        print("Read: ({}) {!r}".format(time.time(), row))
    

    例如,

    $ 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]
    

    您能解释一下为什么需要无缓冲读取CSV文件吗?无论您要做什么,都可能有更好的解决方案。



知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看