Как реализовать асинхронную функцию в python 3 - PullRequest
1 голос
/ 07 марта 2020

Я очень новичок в программировании в целом. Имел некоторый базовый c опыт работы с C ++ и HTML, например, простые калькуляторы и другие действительно базовые c вещи (я начал учиться самостоятельно несколько месяцев go), и из-за этого я даже не уверен если я отправлю этот вопрос правильно. Может быть, это само собой разумеется, но я также новичок в stackoverflow (мой первый пост!), Поэтому я могу сделать некоторые вещи здесь неправильно, и я прошу вас понять. Любая конструктивная критика приветствуется!

Итак, вот моя проблема: я пытаюсь создать простую программу для чата в Python 3, но здесь есть одна загвоздка: я хочу использовать асинхронные возможности python чтобы позволить пользователю завершить программу в любой момент времени, нажмите клавишу es c . Я уже просмотрел несколько библиотек, таких как pynput, asyncio, tornado и getch (). Но независимо от того, как я изменяю свой код, я просто не могу достичь своей цели.

Я сделал асин c функцию с именем runalways(), которая должна выполняться в течение всей продолжительности программы, параллельно с другими функциями. Но это не так, и я не мог понять, почему ...

Извините, если я не смог правильно объяснить свою проблему. Некоторые термины и понятия все еще довольно размыты для меня, но, надеюсь, так будет долго. Я оставлю код, который у меня есть, который хорошо выполняет функцию чата, но это все. Бит asyn c в данный момент практически отсутствует.

Было бы очень признательно, если бы кто-то мог объяснить, что мне не хватает:

import time, asyncio
from msvcrt import getch


# Creates a chat-like effect
def typing(text):
    for i in text:
        print(i, end=" ")
        time.sleep(0.1)
    time.sleep(1.0)


# Terminates the program
def termination():
    print("Program terminated")
    time.sleep(0.5)
    SystemExit


# Defines async function to read pressed keys and terminate if Esc is pressed
# (Not working)
async def runalways():
    while True:
        print(ord(getch()))
        key = ord(getch())
        if key == 27:  # Esc
            termination()


# Initialize chatting
def startChat():
    typing("\nHello!\n")
    typing("How are you?\n\n")
    typing("Answer:\t")
    x = input()
    typing("\nAnyways, that isn't relevant right now.\n")
    time.sleep(0.5)
    typing("Can we get started?\n\n")
    typing("Answer(Y/N):\t")
    x = input()


# validates input
    while (x != "Y") & (x != "N"):
        typing("\nHey, don't go fooling around now. Keep it real! Try again.\n\n")
        typing("Answer(Y/N):\t")
        x = input()
    if (x == "Y") | (x == "y"):
        typing("\nThere you go! Now, let's go through the basics...\n\n")
        termination()

    elif (x == "N") | (x == "n"):
        typing("\nSorry to hear that... See you next time, then!")
        termination()


# Defines starter point for the program
def main():
    runalways()
    startChat()


main()

Я постараюсь сделать все возможное, чтобы уточнить любые вопросы, которые могут помочь в понимании моей проблемы. Заранее спасибо!

1 Ответ

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

У вас есть две функции, конкурирующие за захват ввода. runalways хочет получить их с помощью getch, в то время как ваш основной чат l oop пытается с помощью input. Два процесса конфликтуют; только один может потреблять каждого персонажа. Всякий раз, когда один поток захватывает ввод, другой получает запрос буфера для следующего ввода.

Вместо этого вам нужно настроить один входной канал, который немедленно завершается на ESC; в противном случае он выводит эхо на терминал и передает символ на главный l oop (или буферизует его до появления EOL).

...