Последовательные чтения Python из файла

У меня есть скрипт Python, который читает из файла. Первая команда считает строки. Вторая печатает вторую строку, хотя вторая не работает.

lv_file = open("filename.txt", "rw+")

# count the number of lines =================================
lv_cnt = 0
for row in lv_file.xreadlines():
    lv_cnt = lv_cnt + 1

# print the second line =====================================
la_lines = la_file.readlines()
print la_lines[2]

lv_file.close()

Когда я пишу это так, это работает, но я не понимаю, почему мне пришлось бы закрыть файл и открыть его снова, чтобы он заработал. Есть ли какая-то функциональность, которой я злоупотребляю?

lv_file = open("filename.txt", "rw+")

# count the number of lines =================================
lv_cnt = 0
for row in lv_file.xreadlines():
    lv_cnt = lv_cnt + 1

lv_file.close()

lv_file = open("filename.txt", "rw+")

# print the second line =====================================
la_lines = la_file.readlines()
print la_lines[2]

lv_file.close()

3 ответа

Решение

Файловый объект является итератором. После того, как вы прошли все строки, итератор исчерпан, и дальнейшие чтения ничего не сделают.

Чтобы избежать закрытия и повторного открытия файла, вы можете использовать seek перемотать к началу:

lv_file.seek(0)

Что вы после того, как file.seek():

Пример: (на основе вашего кода)

lv_file = open("filename.txt", "rw+")

# count the number of lines =================================
lv_cnt = 0
for row in lv_file.xreadlines():
    lv_cnt = lv_cnt + 1

lv_file.seek(0)  # reset file pointer

# print the second line =====================================
la_lines = la_file.readlines()
print la_lines[2]

lv_file.close()

Это вернет указатель файла обратно в исходное положение.

pydoc file.seek:

seek(offset, whence=SEEK_SET) Измените позицию потока на заданное байтовое смещение. Смещение интерпретируется относительно позиции, обозначенной откуда. Значения откуда:

SEEK_SET или 0 - начало потока (по умолчанию); смещение должно быть нулевым или положительным SEEK_CUR или 1 - текущая позиция потока; смещение может быть отрицательным SEEK_END или 2 - конец потока; смещение обычно отрицательное. Возвращает новую абсолютную позицию.

Новое в версии 2.7: Константы SEEK_*

Обновление: лучший способ подсчета нет. строк в файле итеративно и касается только 2-й строки:

def nth_line_and_count(filename, n):
    """Return the nth line in a file (zero index) and the no. of lines"""

    count = 0

    with open(filename, "r") as f:
        for i, line in enumerate(f):
            count += 1
            if i == n:
                value = line

    return count, value

nlines, line = nth_line_and_count("filename.txt", 1)

Поскольку xreadlines() сохраняет указатель на последнюю строку, которую он вам отправил, когда вы делаете

la_lines = la_file.readlines()

в основном он запоминает индекс последней строки, которую он вам дал. когда вы закрываете файл и затем открываете его, он создает новый итератор и снова указывает на строку 0.

Другие вопросы по тегам