Работа с файлами в Python: чтение и запись данных
Основы работы с файлами в Python
Наиболее эффективный способ чтения и записи данных в Python - использование встроенной функции open() вместе с менеджером контекста with. Этот подход гарантирует корректное закрытие файла даже при возникновении исключений.
with open('example.txt', 'r', encoding='utf-8') as file:
content = file.read()
print(content)
Python чтение запись (чтение и запись данных в python)
Пояснение: функция open() принимает имя файла, режим (здесь 'r' - чтение) и необязательную кодировку. Менеджер контекста with автоматически закрывает файл после выхода из блока. Метод read() возвращает содержимое файла в виде строки.
Как прочитать файл целиком?
with open('example.txt', 'r') as f:
data = f.read()
Цель: получить всё содержимое файла в одной строковой переменной. Подходит для небольших файлов (до нескольких мегабайт). Проблема: для больших файлов загрузка в память может быть неэффективной.
Типичная ошибка: если файл не существует, возникнет FileNotFoundError. Решение: проверить наличие файла с помощью os.path.exists() или использовать блок try/except.
Как читать файл построчно для экономии памяти?
with open('large_file.log', 'r') as f:
for line in f:
print(line.strip())
Цель: обработка больших файлов без загрузки всего содержимого в память. Итерация по файловому объекту возвращает строки одну за другой.
Проблема: если строки очень длинные, цикл может потреблять много памяти. Решение: использовать f.readline() с ограничением по размеру или f.read(chunk_size) для чтения блоками.
Как записать строку или список строк в файл?
lines = ['строка1', 'строка2', 'строка3']
with open('output.txt', 'w', encoding='utf-8') as f:
for line in lines:
f.write(line + '\n')
Режим 'w' перезаписывает файл, если он существует. Для добавления в конец используйте режим 'a'.
Ошибка: если не указать кодировку, Python использует кодировку по умолчанию, что может привести к UnicodeEncodeError при работе с не-ASCII символами. Решение: всегда явно указывайте encoding='utf-8'.
Как работать с бинарными файлами (изображения, архивы)?
with open('image.png', 'rb') as f:
binary_data = f.read()
# Запись обратно
with open('copy.png', 'wb') as f:
f.write(binary_data)
Режимы 'rb' и 'wb' работают с байтами, а не со строками. Цель: копирование или обработка нетекстовых данных.
Проблема: при чтении больших бинарных файлов (например, видео) одномоментная загрузка в память может привести к переполнению. Решение: читать по частям с помощью f.read(chunk_size).
Как читать и записывать данные в формате JSON?
import json
data = {'name': 'Аня', 'age': 30}
with open('data.json', 'w', encoding='utf-8') as f:
json.dump(data, f, ensure_ascii=False, indent=2)
with open('data.json', 'r', encoding='utf-8') as f:
loaded = json.load(f)
print(loaded)
Цель: сохранение/восстановление структур Python (словари, списки) в стандартном формате обмена данными. Параметр ensure_ascii=False сохраняет кириллицу.
Ошибка: если файл поврежден или содержит невалидный JSON, возникнет json.JSONDecodeError. Решение: проверять данные перед записью и использовать try/except при чтении.
Как обрабатывать CSV-файлы?
import csv
with open('data.csv', 'r', newline='', encoding='utf-8') as f:
reader = csv.reader(f)
for row in reader:
print(row) # каждая строка - список полей
with open('output.csv', 'w', newline='', encoding='utf-8') as f:
writer = csv.writer(f)
writer.writerow(['Имя', 'Баллы'])
writer.writerow(['Иван', 85])
Параметр newline='' предотвращает дублирование переводов строк. Цель: импорт/экспорт табличных данных.
Проблема: разделитель по умолчанию - запятая. Если поля содержат запятые, используйте csv.reader с delimiter=';' или csv.DictReader для работы с заголовками.
Как сериализовать объекты Python с помощью pickle?
import pickle
obj = {'key': [1, 2, 3], 'text': 'пример'}
with open('data.pkl', 'wb') as f:
pickle.dump(obj, f)
with open('data.pkl', 'rb') as f:
loaded_obj = pickle.load(f)
print(loaded_obj)
Цель: сохранение любых объектов Python (включая пользовательские классы) в бинарном формате. Важно: pickle небезопасен для данных из ненадёжных источников.
Ошибка: pickle.UnpicklingError при попытке загрузить данные, сформированные в другой версии Python. Решение: использовать protocol при сохранении или перейти на JSON для совместимости.
Расширенные примеры работы с файлами
Чтение больших файлов по частям (chunks)
chunk_size = 1024 # 1 КБ
with open('bigfile.dat', 'rb') as f:
while True:
chunk = f.read(chunk_size)
if not chunk:
break
# обработать chunk
print(f'Прочитано {len(chunk)} байт')
Прочитано 1024 байт Прочитано 1024 байт Прочитано 512 байт
Пояснение: чтение блоками предотвращает загрузку всего файла в память. Цикл продолжается, пока f.read() возвращает непустые данные.
Одновременное чтение из двух файлов (zip-сопоставление)
with open('names.txt', 'r', encoding='utf-8') as f1, open('scores.txt', 'r', encoding='utf-8') as f2:
for name, score in zip(f1, f2):
print(f'{name.strip()}: {score.strip()}')
Анна: 95 Иван: 80
Цель: построчное объединение данных из двух файлов разного содержания. Используется встроенная функция zip().
Использование seek() и tell() для произвольного доступа
with open('data.bin', 'wb+') as f:
f.write(b'1234567890')
f.seek(0) # вернуться в начало
print(f.read(3)) # b'123'
f.seek(5) # перейти к 6-му байту
print(f.read(2)) # b'67'
print(f.tell()) # текущая позиция: 7
b'123' b'67' 7
Пояснение: seek(offset, whence) перемещает указатель; tell() возвращает текущую позицию в байтах. Цель: работа с бинарными файлами произвольного формата (например, базы данных).
Обработка ошибок и повторное открытие файла
import time
filename = 'log.txt'
for attempt in range(3):
try:
with open(filename, 'r') as f:
data = f.read()
break
except FileNotFoundError:
print(f'Попытка {attempt+1}: файл не найден, ждём...')
time.sleep(1)
else:
print('Не удалось открыть файл после 3 попыток')
Попытка 1: файл не найден, ждём... Попытка 2: файл не найден, ждём... Попытка 3: файл не найден, ждём... Не удалось открыть файл после 3 попыток
Цель: устойчивость к временным проблемам (например, файл создаётся другим процессом).
Создание временных файлов с помощью tempfile
import tempfile
with tempfile.NamedTemporaryFile(mode='w+', delete=False, suffix='.txt') as tmp:
tmp.write('Временные данные')
print(f'Создан временный файл: {tmp.name}')
tmp.seek(0)
print(tmp.read())
# Файл остаётся, так как delete=False
Создан временный файл: /tmp/tmpabc123.txt Временные данные
Пояснение: модуль tempfile генерирует уникальные имена и автоматически удаляет файлы (если delete=True). Цель: безопасное хранение промежуточных данных.
Использование pathlib для удобной работы с путями
from pathlib import Path
base = Path('data/subdir')
base.mkdir(parents=True, exist_ok=True)
file_path = base / 'config.ini'
file_path.write_text('[DEFAULT]\nkey = value\n', encoding='utf-8')
read_back = file_path.read_text(encoding='utf-8')
print(read_back)
[DEFAULT] key = value
Пояснение: класс Path из модуля pathlib предоставляет объектно-ориентированный интерфейс для путей и методов write_text() / read_text(). Цель: упрощение кода и кросс-платформенность.