【问题标题】:StringIO appears to behave different when initialising from a buffer as opposed to writing data into it line by line当从缓冲区初始化而不是逐行将数据写入缓冲区时,StringIO 的行为似乎有所不同
【发布时间】:2020-07-18 07:13:49
【问题描述】:

我正在尝试读取一些数据并将其解析为 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有什么区别?

【问题讨论】:

  • 因为光标在input2中的文件末尾

标签: python csv stringio


【解决方案1】:

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

要修复input2 代码,请在完成编写后回到开头:

input2.seek(0)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-08-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多