我正在尝试创建一个循环python函数,它执行任务并提示用户进行响应,如果用户在给定时间内没有响应,则序列将重复 .
这是基于这个问题的松散基础:How to set time limit on raw_input
该任务由 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"
`
6 回答
警告:这可以按照要求在* nix和OSX中使用,但绝对不能在Windows中使用 .
我使用了this modification的ActiveState配方作为下面代码的基础 . 它是一个易于使用的对象,可以通过超时读取输入 . 它使用轮询一次收集一个字符并模拟
raw_input()
/input()
的行为 .带超时输入
注意:显然下面的
_getch_nix()
方法不适用于OP,但在OSX 10.9.5上它适用于我 . 你可能有运气调用_getch_osx()
虽然它似乎只在32位python中工作,因为Carbon不完全支持64位 .测试一下
重复输入
这实现了我理解它的初衷 . 我认为进行递归调用没有任何 Value - 我认为你想要的只是重复输入?如果错误,请纠正我 .
您可以在输入之前设置警报,然后将警报绑定到自定义处理程序 . 在给定的时间段警报消失后,处理程序引发异常,并且您的自定义
input
函数可以处理其余的事件 .一个简单的例子:
信用到期:Keyboard input with timeout in Python
我不认为有一种方法可以显示一个提示,它将在时间过后过期而不显示另一个线程的不同消息 .
您可以在调用raw_input之前添加以下行:
您可以按如下方式定义
interrupt_user
函数:在
raw_input_with_time
函数中,不要调用sleep . 相反,将调用之前的时间保存到raw_input,并确定调用后经过的时间是否超过5秒 . 此外,如果用户输入'q',则它不应该调用自身,因此循环将停止 .另一种方法是将IO阻塞放在新线程中(与您在主线程中使用它的方案相反) . 需要注意的是,在python中没有一种杀死线程的干净方法,所以这对于重复调用不会很好(N个线程会一直挂到主端,我认为raw_input不能很好...) .
所以,请注意,这一次有效,远非完美的解决方案
这只是概念的教授 . 询问用户输入数据 .
如果不是在输入超时时调用
some_function
,而是将其转换为后续线程并以超时间隔继续运行,该怎么办?当主线程在等待输入时被永久阻止时,工作将继续进行 . 您可能决定根据工作人员的工作(工作或睡眠)对该输入作出不同的反应 - 您可能只是完全忽略它 . AFAIK,不接受输入或接受输入但忽略输入之间没有明显的区别 . 这个想法利用了这一点 .注意:我打算做的就是演示另一种思考问题的方法,这种方式在你的特定情况下可能适合也可能不适合 . 我认为它非常灵活 .
概念证明:
它不依赖于任何特定于平台的东西;它只是简单的Python代码 . 只有在尝试从线程中获取输入的一些替代实现之后,我才意识到将用户输入留给主线程的优势有多大 .
我没有太注意使其安全和清洁,但可以肯定它可以在保持整体结构的同时完成 . 我能看到的最大缺陷是早期的输入永远不会消失 . 当 Worker 输出时,它会导致混淆,掩盖了先前的输入 . 如果您及时按
q
但不按Enter
,则下次按q
和Enter
会导致输入qq
,即使这些q
在屏幕上彼此不相邻也是如此 . 通常这是如何命令行应用程序工作,所以我'm not sure if it'值得修复 . 您可以考虑接受仅包含q
的输入作为取消 . 另一种选择是直接从stdin
读取,而不是使用raw_input
.使代码结构更好的一些想法是使主线程甚至是dumber并让它将所有输入传递给worker(使用队列)来决定如何处理 .