当前位置:  开发笔记 > 编程语言 > 正文

键盘输入在Python中超时

如何解决《键盘输入在Python中超时》经验,为你挑选了5个好方法。

你会如何提示用户输入一些信息但是在N秒后超时?

谷歌在http://mail.python.org/pipermail/python-list/2006-January/533215.html上指向了一个关于它的邮件线程,但似乎没有用.超时发生的语句,无论是sys.input.readline还是timer.sleep(),我总是得到:

:[raw_]输入最多需要1个参数,得2

以某种方式,除了没有抓住.



1> Pontus..:

使用选择呼叫更短,并且应该更加便携

import sys, select

print "You have ten seconds to answer!"

i, o, e = select.select( [sys.stdin], [], [], 10 )

if (i):
  print "You said", sys.stdin.readline().strip()
else:
  print "You said nothing!"


我刚测试过,这对Windows不起作用.Select是可用的,但是在windows上,select的输入只能是socket - sys.stdin,文件描述符是unix.我下次肯定会先测试一下.
该死.那么,自尊的程序员还是使用Windows呢?;)对于简单的用户输入,我想可以通过"kbhit"循环来检测键盘按下,"getch"和"time.sleep"在超时后中断.但它会很难看.

2> 小智..:

您链接到的示例是错误的,并且在调用警报处理程序而不是读取块时实际发生异常.最好试试这个:

import signal
TIMEOUT = 5 # number of seconds your want for timeout

def interrupted(signum, frame):
    "called when read times out"
    print 'interrupted!'
signal.signal(signal.SIGALRM, interrupted)

def input():
    try:
            print 'You have 5 seconds to type in your stuff...'
            foo = raw_input()
            return foo
    except:
            # timeout
            return

# set alarm
signal.alarm(TIMEOUT)
s = input()
# disable the alarm after success
signal.alarm(0)
print 'You typed', s


不错的解决方案,这只适用于Linux.
这对我不起作用.它只是在5秒后打印"中断",但它实际上并没有停止`输入'.它仍然等待按下Enter键,它甚至会在出现"Interrupted"消息后打印我输入的任何文本.使用Python 2和3在Linux上测试.

3> Locane..:

不是Python解决方案,但......

我使用在CentOS(Linux)下运行的脚本来解决这个问题,对我的情况有用的只是在子进程中运行Bash"read -t"命令.我知道,野蛮恶心的黑客,但我对它的运作情况感到内疚,我想与大家分享.

import subprocess
subprocess.call('read -t 30', shell=True)

除非按下ENTER键,否则我需要的是等待30秒的东西.这很有效.



4> Paul..:

这是一个适用于Windows的版本

我无法将这些示例中的任何一个用于Windows,因此我合并了一些不同的StackOverflow答案以获得以下内容:

import threading, msvcrt
import sys

def readInput(caption, default, timeout = 5):
    class KeyboardThread(threading.Thread):
        def run(self):
            self.timedout = False
            self.input = ''
            while True:
                if msvcrt.kbhit():
                    chr = msvcrt.getche()
                    if ord(chr) == 13:
                        break
                    elif ord(chr) >= 32:
                        self.input += chr
                if len(self.input) == 0 and self.timedout:
                    break    


    sys.stdout.write('%s(%s):'%(caption, default));
    result = default
    it = KeyboardThread()
    it.start()
    it.join(timeout)
    it.timedout = True
    if len(it.input) > 0:
        # wait for rest of input
        it.join()
        result = it.input
    print ''  # needed to move to next line
    return result

# and some examples of usage
ans = readInput('Please type a name', 'john') 
print 'The name is %s' % ans
ans = readInput('Please enter a number', 10 ) 
print 'The number is %s' % ans 



5> mike..:

保罗的答案并不奏效.修改后的代码对我有用

Windows 7 x64

vanilla CMD shell(例如,不是 git-bash或其他非M $ shell)

- msvcrt它出现在git-bash中没有任何作用.

python 3.6

(我发布了一个新的答案,因为直接编辑Paul的答案会改变它从python 2.x - > 3.x,这对编辑来说似乎太多了(py2仍在使用中)

import sys, time, msvcrt

def readInput( caption, default, timeout = 5):

    start_time = time.time()
    sys.stdout.write('%s(%s):'%(caption, default))
    sys.stdout.flush()
    input = ''
    while True:
        if msvcrt.kbhit():
            byte_arr = msvcrt.getche()
            if ord(byte_arr) == 13: # enter_key
                break
            elif ord(byte_arr) >= 32: #space_char
                input += "".join(map(chr,byte_arr))
        if len(input) == 0 and (time.time() - start_time) > timeout:
            print("timing out, using default value.")
            break

    print('')  # needed to move to next line
    if len(input) > 0:
        return input
    else:
        return default

# and some examples of usage
ans = readInput('Please type a name', 'john') 
print( 'The name is %s' % ans)
ans = readInput('Please enter a number', 10 ) 
print( 'The number is %s' % ans) 

推荐阅读
帆侮听我悄悄说星星
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有