python 获取键盘输入、同时有超时的功能_python – 循环中具有超时的用户输入...

我正在尝试创建一个循环python函数,它执行任务并提示用户进行响应,如果用户在给定时间内没有响应,则序列将重复.

该任务由some_function()表示.超时是一个变量,以秒为单位.我有以下代码的两个问题:

>无论用户是否提示,raw_input提示在指定的4秒时间后都不会超时.

>当输入’q’的raw_input时(没有”,因为我知道任何键入的内容会自动输入为字符串),该函数不会退出循环.

`

import thread

import threading

from time import sleep

def raw_input_with_timeout():

prompt = "Hello is it me you're looking for?"

timeout = 4

astring = None

some_function()

timer = threading.Timer(timeout, thread.interrupt_main)

try:

timer.start()

astring = raw_input(prompt)

except KeyboardInterrupt:

pass

timer.cancel()

if astring.lower() != 'q':

raw_input_with_timeout()

else:

print "goodbye"

`

解决方法:

警告:这可以按照要求在* nix和OSX中使用,但绝对不能在Windows中使用.

我使用了this modification的ActiveState配方作为下面代码的基础.它是一个易于使用的对象,可以通过超时读取输入.它使用轮询一次收集一个字符并模拟raw_input()/ input()的行为.

输入超时

注意:显然下面的_getch_nix()方法对OP不起作用,但它在OSX 10.9.5上适用于我.你可能有运气调用_getch_osx(),虽然它似乎只能在32位python中工作,因为Carbon不完全支持64位.

import sys

import time

class TimeoutInput(object):

def __init__(self, poll_period=0.05):

import sys, tty, termios # apparently timing of import is important if using an IDE

self.poll_period = poll_period

def _getch_nix(self):

import sys, tty, termios

from select import select

fd = sys.stdin.fileno()

old_settings = termios.tcgetattr(fd)

try:

tty.setraw(sys.stdin.fileno())

[i, o, e] = select([sys.stdin.fileno()], [], [], self.poll_period)

if i:

ch = sys.stdin.read(1)

else:

ch = ''

finally:

termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)

return ch

def _getch_osx(self):

# from same discussion on the original ActiveState recipe:

# http://code.activestate.com/recipes/134892-getch-like-unbuffered-character-reading-from-stdin/#c2

import Carbon

if Carbon.Evt.EventAvail(0x0008)[0] == 0: # 0x0008 is the keyDownMask

return ''

else:

# The event contains the following info:

# (what,msg,when,where,mod)=Carbon.Evt.GetNextEvent(0x0008)[1]

#

# The message (msg) contains the ASCII char which is

# extracted with the 0x000000FF charCodeMask; this

# number is converted to an ASCII character with chr() and

# returned

(what,msg,when,where,mod)=Carbon.Evt.GetNextEvent(0x0008)[1]

return chr(msg & 0x000000FF)

def input(self, prompt=None, timeout=None,

extend_timeout_with_input=True, require_enter_to_confirm=True):

"""timeout: float seconds or None (blocking)"""

prompt = prompt or ''

sys.stdout.write(prompt) # this avoids a couple of problems with printing

sys.stdout.flush() # make sure prompt appears before we start waiting for input

input_chars = []

start_time = time.time()

received_enter = False

while (time.time() - start_time) < timeout:

# keep polling for characters

c = self._getch_osx() # self.poll_period determines spin speed

if c in ('\n', '\r'):

received_enter = True

break

elif c:

input_chars.append(c)

sys.stdout.write(c)

sys.stdout.flush()

if extend_timeout_with_input:

start_time = time.time()

sys.stdout.write('\n') # just for consistency with other "prints"

sys.stdout.flush()

captured_string = ''.join(input_chars)

if require_enter_to_confirm:

return_string = captured_string if received_enter else ''

else:

return_string = captured_string

return return_string

测试一下

# this should work like raw_input() except it will time out

ti = TimeoutInput(poll_period=0.05)

s = ti.input(prompt='wait for timeout:', timeout=5.0,

extend_timeout_with_input=False, require_enter_to_confirm=False)

print(s)

重复输入

这实现了我理解它的初衷.我认为进行递归调用没有任何价值 – 我认为你想要的只是重复输入?如果错误,请纠正我.

ti = TimeoutInput()

prompt = "Hello is it me you're looking for?"

timeout = 4.0

while True:

# some_function()

s = ti.input(prompt, timeout)

if s.lower() == 'q':

print "goodbye"

break

标签:raw-input,python,python-2-7,keyboardinterrupt

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值