【问题标题】:Loop function every x seconds and break loop when condition is no longer met每 x 秒循环一次,当条件不再满足时中断循环
【发布时间】:2021-09-03 14:31:51
【问题描述】:

我正在用 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)消息时,它应该能够为不同的用户运行相同的循环。

对于含糊的解释,我深表歉意。但我希望你能提供帮助。提前致谢!

【问题讨论】:

    标签: python while-loop sched


    【解决方案1】:

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

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

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

    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 - 在这里你会得到关于不同用户的消息)。

    我们有任务(worker),它在我们的“主要”功能处于活动状态时工作。

    【讨论】:

    • 感谢您的回答。我用这段代码测试了很多,但我无法让它按我想要的方式工作。后来我找到了另一种解决方案来达到所需的结果。我仍然认为队列功能会派上用场,感谢您向我展示它!亲切的问候。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-23
    • 2019-04-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多