Сохранение промежуточных данных в txt-файл
Я пишу код по угадыванию чисел.
- Человеку даётся 10000 очков.
- Человек может играть в игру и делать ставки на эти очки.
- Логично,что при победе очки будут прибавлятся.
Мне нужно сделать так, чтобы очки сохранялись при следующем входе в приложение. Сразу в голову пришла идея сделать сохранение последнего числа в .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 шт):
Если делать файлы с сохранениями в виде текстовых файлов с одним значением руками, можно воспользоваться чем-то подобным:
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-ом, ты задаешь значения по умолчанию и все поля будут присутствовать, но есть шанс что значение по умолчанию приведёт в недопустимое состояние. Поэтому версию игры в файле сохранения, а также набор миграций надо иметь в любом случае.