我试图弄清楚如何创建一个可以采用以下参数的小 Python 脚本:
- 提示 - 字符串
- 等待时间为整数
- 停止前的字符数
最后一个是在程序停止接受字符并开始处理输入之前我可以输入的字符数。我见过有些人使用 Python 的 select.select方法,但这并没有考虑到第三项。我倾向于诅咒,虽然我不知道它是否支持让我想到线程的超时。任何见解都会很棒!这将在带有 Python 2.6 的 Linux 上运行。
好的,我已经实现了:D。
#!/usr/bin/env python
import sys
from select import select
def main(argv):
timeout = 3
prompt = '> '
max_chars = 3
# set raw input mode if relevant
# it is necessary to make stdin not wait for enter
try:
import tty, termios
prev_flags = termios.tcgetattr(sys.stdin.fileno())
tty.setraw(sys.stdin.fileno())
except ImportError:
prev_flags = None
buf = ''
sys.stderr.write(prompt)
while True: # main loop
rl, wl, xl = select([sys.stdin], [], [], timeout)
if rl: # some input
c = sys.stdin.read(1)
# you will probably want to add some special key support
# for example stop on enter:
if c == '\n':
break
buf += c
# auto-output is disabled as well, so you need to print it
sys.stderr.write(c)
# stop if N characters
if len(buf) >= max_chars:
break
else:
# timeout
break
# restore non-raw input
if prev_flags is not None:
termios.tcsetattr(sys.stdin.fileno(), termios.TCSADRAIN, prev_flags)
# and print newline
sys.stderr.write('\n')
# now buf contains your input
# ...
if __name__ == "__main__":
main(sys.argv[1:])
它相当不完整;我只是放了一些值来测试它。解释几句:
curses
,end_time
)增加它,然后end_time - current_time
以秒为超时传递到select()
,好的。这个线程闲置了几年,但我花了一个小时探索这个(和相关的)线程以获得一个干净的解决方案。最后,我决定使用已经很好用的工具:bash 的read
. 这是一个要求功率级别的示例。块中的第一行try
解决了手头的问题(当然,这仅在您从 bash shell 启动 python 脚本时才有效。)在这里,您有 3 秒的时间输入最多 3 个字符。(该try
块的其余部分转换为 int 并确保它在预期范围内。)
import os
try:
pwr=os.popen('read -t 3 -n 3 -p "enter power level: " power; echo ${power:-0}').read().strip()
print ''
pwr=int(pwr)
if pwr < 0 or pwr > 100: raise ValueError("valid power levels [0..100]")
print "power=%d"%pwr
except ValueError as e:
print "Illegal Power:", e.message