Чтение файла построчно в 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() # не забываем закрыть вручную, если не используем withPython 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 с отступами).
Расширенные примеры построчного чтения
Пример 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() # удаляем