Как асинхронно распечатать сообщение и изменить его? - PullRequest
0 голосов
/ 15 марта 2020

Итак, я пытался использовать библиотеку asyncio, и ...

Вот моя цель: создать программу, которая периодически отображает сообщение. Это сообщение может быть изменено пользователем в любое время.

Мне кажется, что я близок к решению с помощью следующего кода, но есть одна проблема, которую я не могу решить.

import asyncio
import msvcrt

class PeriodicMessage():
    def __init__(self, message="This is a periodic message. Press M to modify it."):
        self.message = message

    async def write_message(self, sleep_delay=1):
        while True:
            print(self.message)
            await asyncio.sleep(sleep_delay)

    async def change_message(self, sleep_delay=0.01):
        while True:
            if msvcrt.kbhit():
                key_pressed = msvcrt.getch() or None
                if key_pressed == b'm':
                    self.message = input("Enter a new message to display : ")
            await asyncio.sleep(sleep_delay)

    async def main(self):
        await asyncio.gather(self.write_message(), self.change_message())

if __name__ == "__main__":
    periodic_msg = PeriodicMessage()
    asyncio.run(periodic_msg.main())

Если вы запустите это, вы увидите, что сообщение действительно отображается периодически. И вы можете нажать M, чтобы изменить сообщение. Однако проблема заключается в том, что функция «input ()» блокирует программу, делая ее больше не асинхронной. Я где-то читал, что асинхронный ввод в python на самом деле не вещь, но я не мог подтвердить это, так как видел это только из одного источника.

Может быть, я совершенно не прав, и решение Я сейчас исследую это просто не правильно.

Есть идеи? Заранее спасибо!

1 Ответ

0 голосов
/ 17 марта 2020

Лучший способ выполнить sh вашу задачу - установить пакет aioconsole из репозитория PyPI и использовать:

self.message = await ainput("Enter a new message to display: ")

Конечно, в вашей демонстрации вы постоянно выводите сообщения («Это сообщение periodi c ...») несколько мешает продемонстрировать это, поэтому я немного изменил сообщение и удлинил период между выводом сообщения:

import asyncio
from aioconsole import ainput

class PeriodicMessage():
    def __init__(self, message="This is a periodic message. Enter new text to modify it."):
        self.message = message

    async def write_message(self, sleep_delay=5):
        while True:
            print(self.message)
            await asyncio.sleep(sleep_delay)

    async def change_message(self):
        while True:
            self.message = await ainput("Enter a new message to display: ")

    async def main(self):
        await asyncio.gather(self.write_message(), self.change_message())

if __name__ == "__main__":
    periodic_msg = PeriodicMessage()
    loop = asyncio.get_event_loop()
    loop.run_until_complete(periodic_msg.main())
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...