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 в этот момент?


person Al Smith    schedule 06.04.2020    source источник
comment
потому что курсор находится в конце файла в input2   -  person juanpa.arrivillaga    schedule 06.04.2020


Ответы (1)


input2 располагается в конце «файла», тогда как построение StringIO из строки напрямую помещает позицию файла в начало.

Чтобы исправить код input2, вернитесь к началу, когда закончите писать:

input2.seek(0)
person user2357112 supports Monica    schedule 06.04.2020