如何在python中使用asyncio按下和释放?

时间:2019-07-10 05:44:27

标签: python python-asyncio keyboard-events

我想用python做键盘管理器,以加强学习环境。我在将time.sleep()与环境同步时遇到了一些问题

这就是我想要的:

import asyncio
from pynput.keyboard import Key, Controller

class KeyboardManager:
    def __init__(self):
        self.keyboard = Controller()

    def release(self):
        self.keyboard.release(Key.left)
        self.keyboard.release(Key.right)

    async def press_right(self, press_time): 
        self.keyboard.press(Key.right)
        await asyncio.sleep(press_time)
        self.keyboard.release(Key.right)

然后将此类与另一个脚本一起使用

class Env:
    def action_right(self):
        self.keyboard_manager.press_right(10)

此代码无效。
我想我必须在某个地方听异步循环。
有什么好主意吗? 请帮助

1 个答案:

答案 0 :(得分:1)

press_right标记了async函数后,便将其返回值转换为必须在某个地方等待的协程。 您可以通过以下方式将异步传播到Env.action_right

class Env:
    async def action_right(self):
        await self.keyboard_manager.press_right(10)

但是在某些时候,您将不得不等待异步代码。例如,您可以使用loop.run_until_complete()自己处理asyncio事件循环:

from asyncio import get_event_loop

class Env:
    def __init__(self, ...):
        ...
        self.loop = get_event_loop()

    def action_right(self):
        loop.run_until_complete(self.keyboard_manager.press_right(10))

如果您使用的是Python 3.7,则可以:

import asyncio

class Env:
    def action_right(self):
        asyncio.run(self.keyboard_manager.press_right(10))

无论如何,我想您当时不想等待您的异步代码,因为在这种情况下,使KeywordManager.press_right异步是没有意义的。

如果您的框架打算与异步代码一起使用,则事件循环可能由该框架处理,您只需要传播异步代码(例如aiohttp服务器的情况)。相反,如果您使用的是RL库gym,则不会获得此功能,并且我认为使用一些异步代码不会有太大帮助。