Почему readline() не работает после readlines()?

В Python, скажем, у меня есть:

f = open("file.txt", "r")
    a = f.readlines()
    b = f.readline()
    print a
    print b

print a покажет все строки файла, а print b ничего не покажет.

Аналогично наоборот:

f = open("file.txt", "r")
    a = f.readline()
    b = f.readlines()
    print a
    print b

print a показывает первую строку, а print b показывает все строки, кроме первой.

Если и a, и b являются readlines(), a покажет все строки, а b ничего не покажет.

Почему это происходит? Почему обе команды не могут работать независимо друг от друга? Есть ли обходной путь для этого?


person Svavinsky    schedule 14.04.2017    source источник
comment
Readlines читает все строки, поэтому читать нечего, если только вы не вернетесь к началу файла.   -  person Random Davis    schedule 14.04.2017


Ответы (3)


Потому что выполнение .readlines() в первую очередь будет потреблять весь буфер чтения, не оставляя ничего для .readline(), из которого можно было бы извлечь. Если вы хотите вернуться к началу, используйте .seek(0), поскольку @abccd уже упоминалось в его ответе.

>>> from StringIO import StringIO
>>> buffer = StringIO('''hi there
... next line
... another line
... 4th line''')
>>> buffer.readline()
'hi there\n'
>>> buffer.readlines()
['next line\n', 'another line\n', '4th line']
>>> buffer.seek(0)
>>> buffer.readlines()
['hi there\n', 'next line\n', 'another line\n', '4th line']
person shad0w_wa1k3r    schedule 14.04.2017

Поскольку readlines прочитал все строки в файле, так что больше не осталось строк для чтения, чтобы снова прочитать файл, вы можете использовать f.seek(0), чтобы вернуться к началу и прочитать оттуда.

person abccd    schedule 14.04.2017

Файлы имеют смещение в байтах, которое обновляется всякий раз, когда вы их читаете или записываете. Это сделает то, что вы изначально ожидали:

with open("file.txt") as f:
    a = f.readlines()
    f.seek(0)  # seek to the beginning of the file
    b = f.readline()

Теперь a — это все строки, а b — только первая строка.

person U2EF1    schedule 14.04.2017