Запустите функцию, которая завершится только после того, как пользователь выполнит определенную команду

Я создаю бота Discord для игры в покер. У меня есть функция wait_for_betting_to_end, которая определяется следующим образом:

def wait_for_betting_to_end():
    while not_all_players_have_bet():
        pass

У меня есть команда poker внутри cog, которая содержит следующий фрагмент кода:

@commands.command(name='poker')
async def poker(self, ctx):
    self.game_started = True
    # ...
    await preflop()
    wait_for_betting_to_end()
    # ...

У меня есть команда Discord bet внутри cog:

@commands.command(name='bet')
async def bet(self, ctx, amt):
    if not self.game_started:
        print("You're not playing a game.")
        return
    # does something that would make wait_for_betting_to_end stop

Проблема в том, что пользователь никогда не сможет запустить команду bet во время игры в покер; поток выполнения застревает в wait_for_betting_to_end навсегда. Пока не играет, bet правильно отображает ошибку и существует.

Как я могу это исправить?

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
0
60
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Проблема с вашим кодом в том, что вы создаете бесконечный цикл в своей функции wait_for_betting_to_end(). Это ошибка, связанная с мыслью, что discord.py использует многопоточность для получения своей асинхронной функциональности (я могу догадаться об этом, глядя на теги), однако это не так. asyncio работает в одном потоке, где он выполняет задачу (например, получение сообщения, обработка команды и т. д.) и выполняет следующую задачу по завершении этой задачи, сила asyncio проистекает из возможности временно «заморозить» задачу когда прогресс невозможен (например, ожидание ответа или просто сон), чтобы перейти к следующей задаче и возобновить замороженную задачу, когда это необходимо. (Кстати, я почти уверен, что «замораживание» — это совершенно неправильная терминология). Каждая команда, которую получает ваш бот, обрабатывается в отдельной задаче. Вы делаете бесконечный цикл, никогда не освобождаете задачу покера, поэтому он блокирует весь цикл.

Чтобы решить вашу проблему, есть несколько возможностей, например:

Вместо того, чтобы просто бесконечно зацикливаться, вызовите await asyncio.sleep(0.1) вместо pass в своем цикле, это позволит вашему боту получать сообщения от раздора за это время и, таким образом, реагировать на ответы ваших пользователей. Чтобы остановить цикл while, вы можете использовать self.value, для которого вы установили значение False, когда это необходимо (в вашей команде ставок) (возможно, используйте для этого что-то вроде словаря с играми, поскольку вы, вероятно, хотите запускать разные игры одновременно ).

На самом деле я не работаю с Cog, поэтому я не могу с уверенностью дать вам проработанный пример того, как вы могли бы сделать свой код (по крайней мере, не рискуя упустить что-то, что можно легко сделать с помощью Cogs). Но это должно поставить вас на правильный путь, я считаю.

Другие вопросы по теме