Как перенести экземпляр класса из одной функции в другую?

Пишу ВК бота на vkbottle и возникла необходимость использовать экземпляр класса в нескольких местах.

Какая цель: получить входные данные из сообщения пользователя (число), провести некоторые манипуляции с ним в классе Number, ответить пользователю клавиатурой с call-back кнопкой (чтобы не засорять чат), обработать ивент (нажатие по колбек кнопке), и отредактировать сообщение с использованием экземпляра, которого я определил в функции ранее.

@bot.on.private_message(text=["<num:int>"])
async def number_handler(message: Message, num: int):

    new_num = Number(number=num, peer_id=message.peer_id)

    await new_num.f1()

    check_keyboard = (
        Keyboard(inline=True)
        .add(Callback("Сварить вуншпунш", payload={"cmd": "click"}), color=KeyboardButtonColor.POSITIVE)
    )

    await message.answer('''Нажми на кнопку, чтобы увидеть результат''', keyboard=check_keyboard)

@bot.on.raw_event(GroupEventType.MESSAGE_EVENT, MessageEvent, rules.PayloadRule({"cmd": "click"}))
async def edit_message(event: MessageEvent):
    await event.edit_message('''Происходит магия...
    Тыдыщ!''' + "{}".format(new_num.num_i))

Как мне это сделать? При указании PyCharm, понятное дело, пишет, что new_num.num_i это unresolved reference. Или этот экземпляр new_num является локальным и никак его не вытащить? Если так, то было бы здорово обработать входящий ивент внутри первого хендлера, но как это сделать?


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

Автор решения: Павел

Самое очевидное решение - это, конечно, сделать переменную, которая хранит экземпляр класса глобальной.

Вы, возможно, думали, что не можете так сделать, поскольку сам экземпляр создается в процессе работы одной из функций, но на самом деле - это нисколько не мешает.

number = None


class Number:
    def __init__(self, value):
        self.value = value


def foo(value):
    global number
    number = Number(value)


def bar():
    global number
    print(number.value)


foo(5)
bar() # 5
→ Ссылка
Автор решения: Urest

Отказался от изначальной идеи хранить экземпляр класса, и потом получать его контекстно в любом месте. И пришел к решению хранить просто словарь с помощью CtxStorage.

@bot_on.private_message(state=DocInfo.number, text=["<num:int>"])
    async def number_handler(message: Message):

    user_info = {
        'num': message.text,
        'peer_id': message.peer_id
    }

    storage.set(f"{message.from_id}", user_info)

    check_keyboard = (
    Keyboard(inline=True)
    .add(Callback("Напомнить твое число?", payload={"cmd": "click"}), color=KeyboardButtonColor.POSITIVE)
)
    await message.answer('''Нажми на кнопку, чтобы увидеть результат''', keyboard=check_keyboard)

@bot_on.raw_event(GroupEventType.MESSAGE_EVENT, MessageEvent, payload={"cmd": "click"})
async def check_if_paid(event: MessageEvent):
    user = storage.get(f'{event.object.user_id}')
    await event.edit_message(f" Твое число - это {user['num']} ")
→ Ссылка