Файлы: чтение/запись, кодировки, JSON/CSV🔗
От оперативной памяти к файлам🔗
Диаграмма загружается…
Переменные в RAM существуют только во время работы: доступ к ним мгновенный, но при выключении питания всё исчезает. Данные на диске сохраняются годами, как запасы на полках: чтобы получить их, нужно время на поиск и доставку.
При записи текста в файл используется кодировка — иначе символы превратятся в бессмыслицу. UTF-8 — универсальный алфавит с 1114112 возможными символами (220+216), покрывающий латиницу, кириллицу и иероглифы. Текстовый режим хранит человекочитаемые строки, удобные для чтения и редактирования, а бинарный — последовательность машинных байтов для обработки процессором.
Чтобы найти файл, используют путь — указатель на его местоположение:
absolute_path = "/home/chef/recipes/soup.txt" # Абсолютный: от корня системы
relative_path = "recipes/soup.txt" # Относительный: от текущей папки
Открытие и закрытие: риск утечки🔗
Вызов open() сродни запуску кухонного комбайна: пока вы не нажмёте кнопку «стоп» (close()), ресурс остаётся занятым, и другие программы не получат к нему доступ. Забытая команда закрытия ведёт к утечке ресурсов — как техника, работающая всю ночь впустую.
f = open("recipe.txt", "r")
text = f.read()
f.close() # Если ошибка произойдёт выше, до сюда не дойдём
with: автоматическая защита🔗
Конструкция with работает как умная розетка с таймером: файл закроется сам при выходе из блока, даже если внутри произошла ошибка. Гарантия «включил — выключил» выполняется без дополнительных строк.
with open("recipe.txt", "r") as f:
text = f.read()
# Здесь f уже закрыт, освободив ресурс системы
Режимы доступа: уровни допуска🔗
Режимы определяют, что разрешено делать с документом в картотеке:
| Режим |
Действие |
Результат |
r |
Чтение |
Только читать, ошибка если файла нет |
w |
Перезапись |
Создаёт новый или стирает старое безвозвратно |
a |
Дополнение |
Пишет в конец, сохраняя прежнее содержимое |
x |
Создание |
Только новый файл, защита от случайной перезаписи |
Поток строк: работа с лентой🔗
Представьте файл как длинную ленту с гравированными надписями (метафора лекции 9). read() забирает всё содержимое за раз, readline() — следующую строку, а write() наносит текст без автоматического перевода строки — в отличие от print.
with open("recipe.txt", "r") as f:
title = f.readline() # Читаем первую строку
body = f.read() # Остаток файла целиком
Защита от отсутствия файла🔗
Если файл не найден, Python бросает FileNotFoundError (лекция 7). Перехват исключения позволяет программе сообщить о проблеме вместо аварийного завершения:
try:
with open("recipe.txt", "r") as f:
data = f.read()
except FileNotFoundError:
print("Файл с рецептом не найден")
Структурированные данные: CSV и JSON🔗
Парсинг текста вручную через split(',') ненадёжен: запятая внутри названия вроде «сметана, 20%» или случайный перенос строки разорвут логику. CSV и JSON решают эту проблему, сохраняя структуру данных вместе со значениями — именно такие «контейнеры» мы разбирали на восьмой лекции.
CSV напоминает складскую ведомость из Excel. Это плоская таблица: строки — записи, столбцы — свойства. Формат прямо отражает список списков (см. лекцию 8): внешний список — строки таблицы, внутренние — ячейки.
JSON устроен как досье на блюдо с полями 'ингредиенты', 'время', 'шаги'. Данные вложены друг в друга: объект содержит списки, которые содержат другие объекты. Это сериализация словарей и комбинированных структур.
| Формат |
Модель данных |
Когда использовать |
Интерфейс Python |
| CSV |
Таблица (список списков) |
Отчёты, базы, прайсы |
csv.reader, csv.writer |
| JSON |
Иерархия (словари + списки) |
API, конфиги, рецепты |
json.load, json.dump |
import csv
# Список покупок → табличный CSV
with open('покупки.csv', 'w', newline='') as ф:
писатель = csv.writer(ф)
писатель.writerow(['продукт', 'вес_г'])
писатель.writerow(['мука', 300])
import json
# Рецепт → иерархический JSON
рецепт = {"блюдо": "блинчики", "ингредиенты": [{"name": "мука", "кол": 300}]}
with open('рецепт.json', 'w', encoding='utf-8') as ф:
json.dump(рецепт, ф, ensure_ascii=False)
Практика: конвейер файловых операций🔗
Превратим складскую ведомость из CSV в структурированный JSON-файл. Скрипт последовательно читает исходные данные, преобразует их формат и сохраняет результат.
import csv
import json
inventory = []
with open('products.csv', 'r', encoding='utf-8') as src:
reader = csv.DictReader(src)
for row in reader:
item = {
"product": row['name'],
"price": float(row['price'])
}
inventory.append(item)
with open('catalog.json', 'w', encoding='utf-8') as dst:
json.dump(inventory, dst, ensure_ascii=False, indent=2)
Контекстный менеджер with автоматически закрывает файлы даже при ошибках, не требуя ручного вызова close(). Явное указание encoding='utf-8' предотвращает искажение кириллицы, а ensure_ascii=False сохраняет читаемые названия продуктов в JSON. Получается каталог, готовый к обмену между системами без потери данных.