Python 3 定时输入

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15528939/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 20:20:15  来源:igfitidea点击:

Python 3 Timed Input

pythoninputtimerpython-3.xpython-multithreading

提问by cloud311

What I would like to be able to do is ask a user a question using input. For example:

我希望能够做的是使用输入向用户提问。例如:

print('some scenario')
prompt = input("You have 10 seconds to choose the correct answer...\n")

and then if the time elapses print something like

然后如果时间过去了,打印出类似的东西

print('Sorry, times up.')

Any help pointing me in the right direction would be greatly appreciated.

任何为我指明正确方向的帮助将不胜感激。

采纳答案by mediocrity

Interesting problem, this seems to work:

有趣的问题,这似乎有效:

import time
from threading import Thread

answer = None

def check():
    time.sleep(2)
    if answer != None:
        return
    print "Too Slow"

Thread(target = check).start()

answer = raw_input("Input something: ")

回答by jfs

If it is acceptable to block the main thread when user haven't provided an answer:

如果在用户没有提供答案时阻塞主线程是可以接受的:

from threading import Timer

timeout = 10
t = Timer(timeout, print, ['Sorry, times up'])
t.start()
prompt = "You have %d seconds to choose the correct answer...\n" % timeout
answer = input(prompt)
t.cancel()

Otherwise, you could use @Alex Martelli's answer(modified for Python 3) on Windows (not tested):

否则,您可以在 Windows 上使用@Alex Martelli 的答案(针对 Python 3 进行了修改)(未测试):

import msvcrt
import time

class TimeoutExpired(Exception):
    pass

def input_with_timeout(prompt, timeout, timer=time.monotonic):
    sys.stdout.write(prompt)
    sys.stdout.flush()
    endtime = timer() + timeout
    result = []
    while timer() < endtime:
        if msvcrt.kbhit():
            result.append(msvcrt.getwche()) #XXX can it block on multibyte characters?
            if result[-1] == '\n':   #XXX check what Windows returns here
                return ''.join(result[:-1])
        time.sleep(0.04) # just to yield to other processes/threads
    raise TimeoutExpired

Usage:

用法:

try:
    answer = input_with_timeout(prompt, 10)
except TimeoutExpired:
    print('Sorry, times up')
else:
    print('Got %r' % answer)

On Unix you could try:

在 Unix 上,您可以尝试:

import select
import sys

def input_with_timeout(prompt, timeout):
    sys.stdout.write(prompt)
    sys.stdout.flush()
    ready, _, _ = select.select([sys.stdin], [],[], timeout)
    if ready:
        return sys.stdin.readline().rstrip('\n') # expect stdin to be line-buffered
    raise TimeoutExpired

Or:

或者:

import signal

def alarm_handler(signum, frame):
    raise TimeoutExpired

def input_with_timeout(prompt, timeout):
    # set signal handler
    signal.signal(signal.SIGALRM, alarm_handler)
    signal.alarm(timeout) # produce SIGALRM in `timeout` seconds

    try:
        return input(prompt)
    finally:
        signal.alarm(0) # cancel alarm