📝 Python

with open: работа с файлами правильно

P
Автор
PyLand Team
📅
Опубликовано
03.04.2026
⏱️
Время чтения
2 мин
👁️
Просмотров
384
🌿
Уровень
Средний

Файлы сохраняют данные между запусками программы, а конструкция with гарантирует корректное закрытие файла даже при ошибке.

Зачем нужны файлы?

Данные в переменных живут только пока работает программа. При закрытии — всё теряется.

# Без файла: данные пропадут при закрытии программы
score = 100
player = "Рик"

# С файлом: данные сохраняются между запусками
with open("save.txt", "w") as f:
    f.write(f"{player}\n{score}\n")

without vs with: почему важен контекстный менеджер

# Старый способ — легко забыть закрыть файл
f = open("data.txt", "w")
f.write("Данные")
f.close()  # Если до этого упала ошибка — файл не закроется!

# Правильный способ — with закрывает файл автоматически
with open("data.txt", "w") as f:
    f.write("Данные")
# Файл закрыт здесь, даже если внутри была ошибка

Режим “w” — запись

with open("battle_log.txt", "w") as f:
    f.write("=== ЛОГ БИТВЫ ===\n")
    f.write("Рик атакует Ходока\n")
    f.write("Урон: 20\n")

Внимание: режим "w" перезаписывает файл полностью при каждом открытии.

class Player:
    def __init__(self, name):
        self.name = name
        self.kills = 0
        self.health = 100

    def save(self):
        with open(f"saves/{self.name}.txt", "w") as f:
            f.write(f"{self.name}\n")
            f.write(f"{self.kills}\n")
            f.write(f"{self.health}\n")
        print(f"Сохранено: {self.name}")

player = Player("Рик")
player.kills = 5
player.save()

Режим “r” — чтение

with open("saves/Рик.txt", "r") as f:
    content = f.read()       # Весь файл строкой
    print(content)

Способы чтения

with open("saves/Рик.txt", "r") as f:
    name   = f.readline().strip()   # Первая строка
    kills  = f.readline().strip()   # Вторая строка
    health = f.readline().strip()   # Третья строка

print(f"{name}: {kills} убийств, {health} HP")
with open("battle_log.txt", "r") as f:
    lines = f.readlines()  # Список строк

for line in lines:
    print(line.strip())

strip() убирает символ \n в конце строки.

class Player:
    @staticmethod
    def load(name):
        with open(f"saves/{name}.txt", "r") as f:
            loaded_name = f.readline().strip()
            kills  = int(f.readline().strip())
            health = int(f.readline().strip())

        p = Player(loaded_name)
        p.kills  = kills
        p.health = health
        return p

rick = Player.load("Рик")
print(f"{rick.name}: {rick.kills} убийств, {rick.health} HP")

Режим “a” — дозапись

Режим "a" добавляет в конец файла, не удаляя предыдущее содержимое:

with open("log.txt", "w") as f:
    f.write("Лог запущен\n")

# Позже добавляем события
with open("log.txt", "a") as f:
    f.write("Рик убил Ходока\n")

with open("log.txt", "a") as f:
    f.write("Дэрил убил Бегуна\n")

# Файл:
# Лог запущен
# Рик убил Ходока
# Дэрил убил Бегуна

Таблица режимов

Режим Что делает Если файла нет
"r" Читает Ошибка
"w" Записывает (перезаписывает) Создаёт
"a" Добавляет в конец Создаёт

Частые ошибки

Ошибка 1: Забыли режим

# ❌ По умолчанию "r" — нельзя писать
with open("data.txt") as f:
    f.write("Данные")  # UnsupportedOperation: not writable

# ✅ Указывай режим явно
with open("data.txt", "w") as f:
    f.write("Данные")

Ошибка 2: Файл не найден

# ❌ Файл отсутствует
with open("saves/данные.txt", "r") as f:
    content = f.read()  # FileNotFoundError

# ✅ Обработка ошибки
try:
    with open("saves/данные.txt", "r") as f:
        content = f.read()
except FileNotFoundError:
    print("Файл не найден — начинаем заново")
    content = ""

Пользовательский контекстный менеджер

with работает с любым объектом, реализующим __enter__ и __exit__:

class Timer:
    import time

    def __enter__(self):
        import time
        self.start = time.time()
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        import time
        elapsed = time.time() - self.start
        print(f"Время выполнения: {elapsed:.3f}s")
        return False  # False — не подавлять исключения

with Timer():
    total = sum(range(1_000_000))
# Время выполнения: 0.031s

__enter__ выполняется при входе в блок with, __exit__ — при выходе (в том числе при ошибке).

Ваша реакция на статью

💬 Комментарии (0)

🔐 Войдите в систему, чтобы оставить комментарий
🚪 Войти
💭

Комментариев пока нет

Станьте первым, кто поделится мнением об этой статье!

🔗 Похожие

Похожие статьи

Продолжите изучение с этими материалами

📝

if __name__ == "__main__": точка входа Python

Конструкция if name == "main" определяет точку входа Python-программы: она помогает отличить прямой запуск файла...

📅 14.08.2026 👁️ 44
📝

strip() и lower(): подготавливаем пользовательски…

Пользователь может ввести правильное слово с лишними пробелами или буквами другого регистра. Для Python строки...

📅 11.08.2026 👁️ 50
📝

ord(), chr() и циклический сдвиг букв в Python 🔐

Строка состоит из символов, но компьютер хранит каждый символ как числовой код. Python позволяет переходить...

📅 09.08.2026 👁️ 89