Asyncio печатает что-то, ожидая ввода пользователя

У меня есть простой скрипт, я хочу, чтобы пользователь мог вводить что-то, когда захочет, но я также хочу что-то распечатать в середине, это мой код:

import asyncio

async def user_input():
   while True:
        content = input('> ')


async def print_something():
    await asyncio.sleep(10)
    print('something')


async def main():
    tasks = [user_input(), print_something()]
    await asyncio.gather(*tasks)


loop = asyncio.get_event_loop()
loop.run_until_complete(main())
loop.close()

Он позволяет мне вводить, но не печатает something, как мне этого добиться?

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
2
0
2 553
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Короткий ответ: асинхронность не может делать то, что вы хотите. Хотя вы объявили свои функции асинхронными, функция Python input не является асинхронной, это блокирующая функция. Таким образом, он заблокирует цикл событий, и больше ничего не будет выполняться.

Некоторое время назад я ответил на вопрос, который как бы объясняет, как работает асинхронность в python. Я свяжу это. Но чтобы делать то, что вы хотите, вам нужно использовать потоки, а не асинхронные. https://stackoverflow.com/a/63237798/9270488

Если вы хотите использовать потоки с асинхронностью, загляните в ThreadExecutor

Ответ принят как подходящий

input — это функция блокировки, и ее нельзя напрямую использовать с внутренними сопрограммами. Но вы можете запустить его в отдельной теме с помощью run_in_executor:

import asyncio


async def user_input():
    while True:
        loop = asyncio.get_event_loop()
        content = await loop.run_in_executor(None, input, "> ")
        print(content)


async def print_something():
    await asyncio.sleep(5)
    print('something')


async def main():
    tasks = [user_input(), print_something()]
    await asyncio.gather(*tasks)


loop = asyncio.get_event_loop()
loop.run_until_complete(main())
loop.close()

Обновление: также вы можете использовать библиотеку aioconsole, которая предоставляет консольные функции на основе asyncio:

from aioconsole import ainput

async def user_input():
    while True:
        content = await ainput(">")
        print(content)

Боже мой, спасибо, каждый второй ответ рекомендует 10-30 строк заводской упаковки java-esque для стандартного ввода и стандартного вывода, а не просто использовать уже существующую функцию «ввода». Это должен быть ответ на все остальные вопросы.

Rebs 16.02.2022 04:27

Другие вопросы по теме