Сохранение промежуточных данных в txt-файл

Я пишу код по угадыванию чисел.

  1. Человеку даётся 10000 очков.
  2. Человек может играть в игру и делать ставки на эти очки.
  3. Логично,что при победе очки будут прибавлятся.

Мне нужно сделать так, чтобы очки сохранялись при следующем входе в приложение. Сразу в голову пришла идея сделать сохранение последнего числа в .txt,но возникла проблема - иногда число само берёт и удаляется из файла .txt и он становится пустой, либо код сам перестаёт читать данные из файла и оставляет пустоту. Вот код .txt -

f = text_file = open("money.txt", "r+")
if f =="":
    f = text_file.write("10000") 
    f.close
f = f.read()
money = f
money = str(money)

Ответы (1 шт):

Автор решения: outoftime

Если делать файлы с сохранениями в виде текстовых файлов с одним значением руками, можно воспользоваться чем-то подобным:

DEFAULT_MONEY_VALUE = 10000
MONEY_SAVE_FILENAME = "money.txt"

def read_money_value() -> int:
    """Raises OSError and ValueError"""
    with open(MONEY_SAVE_FILENAME, "r") as f:
        data = f.read() or DEFAULT_MONEY_VALUE
        return int(data)

def write_money_value(value: int) -> None:
    """Raises OSError and UnicodeEncodeError"""
    with open(MONEY_SAVE_FILENAME, "w") as f:
        f.write(str(value))

if __name__ == "__main__":
    try:
        money = read_money_value()
    except (OSError, ValueError):
        money = DEFAULT_MONEY_VALUE
    # ...
    try:
        write_money_value(money)
    except (OSError, UnicodeEncodeError) as e:
        print("{}\n".format(e))
        exit(1)

В общем случае, проще использовать json, а лучше pickle. Чтобы легче было проверять результат, привёл пример с json-ом:

import json

class GameState(object):
    DEFAULT_MONEY_VALUE = 10000

    def __init__(self, **kw):
        self.money = kw.get("money", self.DEFAULT_MONEY_VALUE)

class SaveManager(object):
    SAVE_FILENAME = "save.txt"

    @classmethod
    def load(cls) -> GameState:
        try:
            with open(cls.SAVE_FILENAME, "r") as f:
                data = json.load(f)
                return GameState(**data)
        except:
            return GameState()

    @classmethod
    def write(cls, state: GameState) -> None:
        with open(cls.SAVE_FILENAME, "w") as f:
            return json.dump(
                state, 
                f, 
                default=lambda o: o.__dict__, 
                sort_keys=True, 
                indent=4)

if __name__ == "__main__":
    state = SaveManager.load()
    state.money += 1
    SaveManager.write(state)

Если использовать pickle, придётся иметь дело с миграциями. К примеру, добавится ещё одно поле в объект состояния игры, а в прошлой версии этого поля нету. При чтении, ты получишь объект без нужного поля. В тоже время, в примере с json-ом, ты задаешь значения по умолчанию и все поля будут присутствовать, но есть шанс что значение по умолчанию приведёт в недопустимое состояние. Поэтому версию игры в файле сохранения, а также набор миграций надо иметь в любом случае.

→ Ссылка