Как избавиться от глобальных переменных в коде бота для телеграмм?
Мне нужно обмениваться информацией между хендлерами.
Решил использовать глобальные переменные, но как выяснилось это плохая идея, каждый пользователь бота в любой момент может поменять значение этой переменной и для другого пользователя хендлер сработает не так как нужно. Как я понял это так работает.
На ум пришло использовать словари в качестве глобальных переменных, где ключом будет айди пользователя, так пользователи не будут мешать друг другу, была так же идея вместо переменных использовать базу данных, что бы хендлеры брали информацию оттуда.
Каким способом решить мою проблему будет лучше всего?
Ответы (2 шт):
Начну с банального.
Файлы. Хранить можно в json. к примеру.
Redis. (отличный варинт)
Базы данных. sql/nosql
Можно хранить и в памяти(глобальных переменных). Просто данные сохраняться не будут между сессиями.
А насчёт как лучше -> всё зависит от типа и количества хранимых данных, масштабности приложения, нагрузки приложения.
В дополнении к ответу @Exord'a можно юзать тот же MongoDB или Redis, но нужно немного модифицировать класс этих модулей.
Пример.
import typing
from aiogram import Bot, Dispatcher, executor, types
from aiogram.contrib.fsm_storage.memory import MemoryStorage
from aiogram.dispatcher import FSMContext
import config
bot = Bot(token=config.BOT_TOKEN)
class GlMemoryStorage(MemoryStorage):
async def reset_state(self, *,
chat: typing.Union[str, int, None] = None,
user: typing.Union[str, int, None] = None,
with_data: typing.Optional[bool] = True):
await self.set_state(chat=chat, user=user, state=None)
if with_data:
new_data = {}
old_data = await self.get_data(chat=chat, user=user)
for key, value in old_data.items():
if key.startswith("_"):
new_data[key] = value
await self.set_data(chat=chat, user=user, data=new_data)
self._cleanup(chat, user)
storage = GlMemoryStorage()
dp = Dispatcher(bot, storage=storage)
@dp.message_handler(commands=['start'])
async def start(message: types.Message, state: FSMContext):
async with state.proxy() as data:
data["_asd"] = 123
data["asd"] = 1234
await state.finish()
async with state.proxy() as data:
print(data)
Вывод:
FSMContextProxy state = , data = {'_asd': 123}
Вот так можно по аналогии с MemoryStorage сделать уже с Redis и MongoDB (чтобы при рестарте не сбрасывались данные). Такие себе не удаляемые переменные. Только ручное удаление.