Как нажать и отпустить, используя asyncio в Python? - PullRequest
0 голосов
/ 10 июля 2019

Я хочу сделать менеджер клавиатуры с python для environemnt обучения подкреплению. У меня есть проблема с 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 Ответ

1 голос
/ 10 июля 2019

После того, как вы пометили функцию press_right с помощью async, вы конвертируете ее возвращаемое значение в сопрограмму, которую нужно где-то ожидать. Вы можете просто распространять асинхронность до Env.action_right следующим образом:

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

Но в какой-то момент вам придется подождать ваш асинхронный код. Например, вы можете самостоятельно обработать цикл событий asyncio с помощью loop.run_until_complete():

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, вам не предоставляется такая возможность, и я не думаю, что использование какого-либо асинхронного кода окажет большую помощь.

...