Чтение файла построчно в Python: способы, код, типичные ошибки

Раздел: Python -> Файловый ввод-вывод

Построчное чтение файлов в Python

Построчная обработка текстовых файлов одна из самых частых задач при работе с данными. Файлы могут быть огромными (логи, CSV, конфиги), поэтому важно выбирать эффективный метод, который не загружает весь файл в память. Ниже разобраны основные подходы с примерами кода, пояснениями и указанием типичных ошибок.

Как эффективно читать файл построчно без загрузки в память целиком?

Наиболее предпочтительный способ использовать конструкцию with open(...) as f: и итерироваться по файловому объекту. Файл открывается как итератор, который лениво возвращает строки из буфера. Этот метод автоматически закрывает файл после выхода из блока with.

with open('data.txt', 'r', encoding='utf-8') as f:
    for line in f:
        print(line.rstrip())   # используем .rstrip(), чтобы убрать символ \n

ввод программ на python (ввод данных в программе python)

Пояснение:

  • open('data.txt', 'r') открывает файл в режиме чтения (текстовом). Явно указана кодировка UTF-8.
  • with ... as f: контекстный менеджер гарантирует закрытие файла даже при возникновении исключения.
  • for line in f: читает строку за строкой, не загружая весь файл сразу.
  • line.rstrip() удаляет пробельные символы справа, включая символ новой строки (\n или \r\n).

Типичная ошибка и решение:

Забывают указать аргумент encoding. Если файл содержит не-ASCII символы, может возникнуть UnicodeDecodeError. Всегда указывайте кодировку, например encoding='utf-8'. Если файл в cp1251, используйте encoding='cp1251'.

Другая ошибка: при использовании .strip() вместо .rstrip() могут удалиться важные пробелы в начале строки. Для удаления только символа перевода строки лучше применять line.rstrip('\n') или line.rstrip(), если пробелы в конце незначимы.

Как читать файл с помощью метода readline() для более тонкого управления?

Метод readline() читает одну строку за вызов. Подходит, если требуется контролировать позицию чтения или обрабатывать файл по частям с условными остановками.

file = open('data.txt', 'r', encoding='utf-8')
while True:
    line = file.readline()
    if not line:          # readline() возвращает пустую строку в конце файла
        break
    print(line.rstrip())
file.close()  # не забываем закрыть вручную, если не используем with

Python file io (ввод-вывод файлов в python)

Пояснение:

Цикл выполняется, пока readline() не вернёт пустую строку. Файл нужно закрыть явно. В современных версиях Python лучше использовать with, но данный подход полезен, когда файл нужно открыть однократно, а читать из разных мест (например, после перемотки file.seek()).

Возможные проблемы:

Если файл содержит пустую строку в середине, readline() вернёт строку "\n", которая не является пустой (bool("\n") == True). Условие if not line сработает только на реальный конец файла. Пустую строку нужно проверять отдельно: if line == '': break после line = file.readline(). Тут путаница: если файл закончился, возвращается '', а если пустая строка - '\n'.

Как загрузить все строки в список с помощью readlines()?

Метод readlines() возвращает список всех строк файла. Используется, когда файл небольшой и все строки нужны в памяти для дальнейшей обработки (например, сортировка).

with open('data.txt', 'r', encoding='utf-8') as f:
    lines = f.readlines()
for i, line in enumerate(lines):
    print(f"{i+1}: {line.rstrip()}")

Python temp files (временные файлы в python)

Пояснение:

Каждая строка в списке сохраняется вместе с символом новой строки. При большом файле (сотни МБ) этот подход может привести к нехватке памяти.

Ошибка использования с большими файлами:

Вызов readlines() на файле размером 10 ГБ вызовет OverflowError или систему убьёт процесс OOM. Для больших файлов используйте итерацию по самому файловому объекту.

Как получить номер строки при чтении с помощью enumerate?

Встроенная функция enumerate() добавляет счётчик строк. Удобно для логов и отладки.

with open('data.txt', 'r', encoding='utf-8') as f:
    for num, line in enumerate(f, 1):   # start=1
        print(f"{num}: {line.rstrip()}")

Python index files (индексация файлов в python)

Пояснение:

enumerate(f, 1) начинает счёт с 1. Без второго аргумента счёт шёл бы с 0.

Как читать строки из нескольких файлов или из стандартного ввода с помощью fileinput?

Модуль fileinput позволяет обрабатывать строки из нескольких файлов, переданных как аргументы командной строки, а если их нет, то из sys.stdin. Это очень удобно для скриптов-фильтров.

import fileinput

for line in fileinput.input():
    line = line.rstrip()
    # fileinput.filename() возвращает имя текущего файла
    # fileinput.lineno() возвращает глобальный номер строки
    print(f"{fileinput.filename()}:{fileinput.filelineno()} - {line}")

File python class (класс для работы с файлами в python)

Пояснение:

Если запустить скрипт как python script.py file1.txt file2.txt, то строки будут последовательно читаться из обоих файлов. Если файлы не указаны, чтение идёт из stdin. С помощью fileinput.isfirstline() можно определить начало нового файла.

Проблемы:

Каждая строка приходит с символом перевода строки (включая последнюю строку, если в конце файла нет \n). Нужно аккуратно чистить. Также fileinput по умолчанию не изменяет файлы, но может использоваться с inplace=True для редактирования на месте (опасно).

Как прочитать все строки в одну переменную с помощью pathlib и splitlines?

Метод Path.read_text() читает весь файл как строку, затем .splitlines() разбивает её на список строк (без символов перевода строки). Подходит только для маленьких файлов.

from pathlib import Path

lines = Path('data.txt').read_text(encoding='utf-8').splitlines()
for line in lines:
    print(line)

Python file utf 8 (кодировка utf-8 для файлов в python)

Пояснение:

splitlines() удаляет все символы переноса строки (в отличие от split('\n'), который оставит пустую строку в конце, если файл заканчивается на \n).

Как правильно обработать кодировки файлов?

Всегда указывайте параметр encoding при открытии файла. Если кодировка неизвестна, можно попробовать модуль chardet или использовать errors='replace' для замены нечитаемых символов.

with open('data.txt', 'r', encoding='utf-8', errors='replace') as f:
    for line in f:
        print(line)

Python config files (конфигурационные файлы в python)

Как удалить символы перевода строки из прочитанных строк?

Для удаления только символа новой строки используйте line.rstrip('\n') или line.rstrip() для удаления всех пробельных символов справа. Если нужно сохранить пробелы в конце строки, лучше line.rstrip('\r\n').

with open('data.txt') as f:
    for line in f:
        stripped = line.rstrip('\n')   # оставит \r, если используется Windows
        # или более надёжно: stripped = line.rstrip('\r\n')
        print(repr(stripped))

Ошибка: использование .strip() удалит пробелы и в начале строки, что может исказить данные (например, в CSV с отступами).

- Python file methods (методы работы с файлами в python)
- File models in python (модели файлов в python)
- File handle python (обработка файлов в python)

Расширенные примеры построчного чтения

Пример 1: Чтение файла с фильтрацией строк

Пример
with open('data.txt', 'r', encoding='utf-8') as f:
    for line in f:
        line = line.strip()
        if line.startswith('#'):
            continue   # пропускаем комментарии
        print(line)
Вывод: содержимое файла без строк, начинающихся на #

Пример 2: Использование fileinput для конкатенации файлов

Пример
import fileinput

# Создадим файлы для демонстрации
with open('a.txt', 'w') as f:
    f.write('строка из A\n')
with open('b.txt', 'w') as f:
    f.write('строка из B\n')

# Чтение из обоих файлов
for line in fileinput.input(['a.txt', 'b.txt']):
    print(f"{fileinput.filename()}: {line}", end='')
a.txt: строка из A
b.txt: строка из B

Пример 3: Чтение строки с номером и запись в словарь

Пример
result = {}
with open('config.ini', 'r', encoding='utf-8') as f:
    for i, line in enumerate(f, 1):
        if '=' in line:
            key, val = line.rstrip().split('=', 1)
            result[key.strip()] = val.strip()
        elif line.strip() == '':
            pass  # пропуск пустых строк
        else:
            print(f"Строка {i}: неверный формат: {line!r}")

Пример 4: Чтение большого файла с прогресс-баром

Пример
import os

def count_lines(path):
    # Быстрый подсчёт строк для прогресс-бара (не обязательно)
    with open(path, 'rb') as f:
        count = sum(1 for _ in f)
    return count

def process_large_file(path):
    total = count_lines(path)
    with open(path, 'r', encoding='utf-8') as f:
        for i, line in enumerate(f, 1):
            # Обработка строки
            if i % 1000 == 0:
                print(f"Обработано {i}/{total}", end='\r')
        print()

process_large_file('big_log.txt')

Пример 5: Обработка ошибок кодировки с заменой

Пример
with open('file_cp1251.txt', 'r', encoding='cp1251', errors='replace') as f:
    for line in f:
        print(line.rstrip())

Пример 6: Чтение файла с BOM (UTF-8 with BOM)

Пример
with open('file_bom.txt', 'r', encoding='utf-8-sig') as f:
    for line in f:
        print(line.rstrip())

Результат: BOM (\ufeff) автоматически удалён из первой строки.

Пример 7: Использование readlines() с распределением строк по частям

Пример
def read_chunks(file_path, chunk_size=10):
    with open(file_path, 'r', encoding='utf-8') as f:
        while True:
            lines = f.readlines(chunk_size)
            if not lines:
                break
            for line in lines:
                yield line.rstrip()

for line in read_chunks('big_file.txt', 5):
    print(line)

Пример 8: Работа с временными файлами и pathlib

Пример
from pathlib import Path
import tempfile

# Создадим временный файл
with tempfile.NamedTemporaryFile(mode='w', delete=False, suffix='.txt') as tmp:
    tmp.write('line1\nline2\nline3\n')
    temp_path = tmp.name

# Прочитаем с помощью pathlib
lines = Path(temp_path).read_text(encoding='utf-8').splitlines()
print(lines)  # ['line1', 'line2', 'line3']
Path(temp_path).unlink()  # удаляем

Чтение файла построчно в Python - comments

En
File python input 0 line 1 (python)