首页 > 解决方案 > 当从缓冲区初始化而不是逐行将数据写入缓冲区时,StringIO 的行为似乎有所不同

问题描述

我正在尝试读取一些数据并将其解析为 CSV。有问题的数据格式带有我首先需要摆脱的古怪的第一行。

delimiter = None
with open('data.csv', 'r', encoding='latin1') as fd:
    input1 = io.StringIO(fd.read())

with open('data.csv', 'r', encoding='latin1') as fd:
    input2 = io.StringIO()
    for line in fd:
        if line.startswith('sep='):
            delimiter = line[4]
        else:
            input2.write(line)

with open('data.csv', 'r', encoding='latin1') as fd:
    buf = ''
    for line in fd:
        if line.startswith('sep='):
            delimiter = line[4]
        else:
            buf += line
    input3 = io.StringIO(buf)

如果我确实添加了第一行,那么 input1.getvalue() == input2.getvalue() == input3.getvalue()。如果我不这样做,那么至少 input2.getvalue() == input3.getvalue()。

然后是 CSV 位:

inputReader = csv.DictReader(inputX, delimiter=delimiter or ';')
for row in inputReader:
    print(row)

这适用于 input1,但由于第一行古怪,它如预期的那样弄乱了列名。

它适用于 input3,具有正确的列名。我很好奇为什么 for 循环没有为 input2 返回任何结果。那时 input2 和 input3 有什么区别?

标签: pythoncsvstringio

解决方案


input2位于“文件”的末尾,而StringIO从字符串构造 a 直接将文件位置放在开头。

要修复input2代码,请在完成编写后重新开始:

input2.seek(0)

推荐阅读