首页 > 解决方案 > 每 x 秒循环一次,当条件不再满足时中断循环

问题描述

我正在用 python 编写一个不和谐的机器人,我在使用下一个功能时遇到了困难。当消息:('user'joined) 被读取时,机器人应该开始每 x 秒循环一次函数,直到消息:('user' left) 被读取。

我一直在临时文件中测试不同的代码。它成功地在“用户”加入时开始循环。但是当('user' left)消息应该通过时,它不会接受新参数并永远继续循环。

这两个版本看起来最有前途:

import re
import time



def message(servermessage):
    a = re.sub("[^\S]", " ", servermessage).split()
    if a[1] == 'joined':
        online = False

    elif a[1] == 'left':
        online = True

    while True:
        mcusername = a[0]
        print(mcusername, 0)
        if online:
            break
        time.sleep(2)



message('user joined')
time.sleep(10)
message('user left')

import re
import sched, time

s = sched.scheduler(time.time, time.sleep)

def message(servermessage):
    a = re.sub("[^\S]", " ", servermessage).split()
    def rewardplayer():
        s.enter(1, 1, rewardplayer)
        mcusername = a[0]
        print(mcusername, 0)
    if a[1] == 'joined':
        s.enter(1, 1, rewardplayer)
        s.run()

    elif a[1] == 'left':
        s.cancel()


message('user joined')
time.sleep(10)
print('done')
message('user left')


我的另一个要求是,当在前一个用户的('previoususer' left)消息之前给出('newuser'joined)消息时,它应该能够为不同的用户运行相同的循环。

我为模糊的解释道歉。但我希望你能提供帮助。提前致谢!

标签: pythonwhile-loopsched

解决方案


关于您的第一个代码:当在线为 True时,您有while应该被破坏的代码。但它在那个循环内永远不会改变。所以它类似于死锁。

关于您的第二个代码:您正在使用“调度程序”。通常这意味着您想定期运行一些事件。但是您的目标是在事件发生时做出反应。在任何时候。没有预定。

所以在这里我可以推荐你使用异步python方式。(请阅读异步)

import re
import asyncio


async def process_msgs(queue):
    while True:
        msg = await queue.get()
        online, usr_name = parse_msg(msg)
        print(usr_name, 0)
        queue.task_done()


def parse_msg(msg):
    result = re.sub("[^\S]", " ", msg).split()
    action = result[1]
    usr_name = result[0]
    if action == 'joined':
        online = False
    elif action == 'left':
        online = True
    return online, usr_name


async def main():
    queue = asyncio.Queue()
    queue.put_nowait('usr joined')
    task = asyncio.create_task(process_msgs(queue))
    queue.put_nowait('usr left')
    await queue.join()
    task.cancel()

asyncio.run(main())

你可以这样使用它。我们有一个队列,我们​​把我们的事件放在那里。你也可以通过无限的方式来做到这一点(听 socket 或 smthg - 在这里你会得到关于不同用户的消息)。

我们有任务(工人),它在我们的“主要”功能还活着的时候工作。


推荐阅读