gpt4 book ai didi

python - 用户输入超时,循环

转载 作者:太空狗 更新时间:2023-10-29 19:26:39 24 4
gpt4 key购买 nike

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

这大致基于这个问题:How to set time limit on raw_input

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

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

  2. 当输入 'q' 的 raw_input 时(没有 '' 因为我知道输入的任何内容都会自 Action 为字符串输入)该函数不会退出循环。

`

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)

重复输入

这实现了我理解的你的初衷。我认为进行递归调用没有任何值(value) - 我认为您想要的只是重复输入?如有不妥请指正。

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

关于python - 用户输入超时,循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32193435/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com