0

我试图弄清楚如何创建一个可以采用以下参数的小 Python 脚本:

  1. 提示 - 字符串
  2. 等待时间为整数
  3. 停止前的字符数

最后一个是在程序停止接受字符并开始处理输入之前我可以输入的字符数。我见过有些人使用 Python 的 select.select方法,但这并没有考虑到第三项。我倾向于诅咒,虽然我不知道它是否支持让我想到线程的超时。任何见解都会很棒!这将在带有 Python 2.6 的 Linux 上运行。

4

2 回答 2

7

好的,我已经实现了: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:])

它相当不完整;我只是放了一些值来测试它。解释几句:

  1. 您需要将 tty 切换到“原始”模式 - 否则如果没有通过 enter 键确认,您将无法获得输入,
  2. 在原始模式下,默认情况下不再输出输入的字符 - 如果您希望用户看到他正在输入的内容,您需要自己输出它们,
  3. 你可能想要处理特殊的键,比如回车和退格——我在这里添加了回车处理。也许你可以重复使用其中的一部分curses
  4. 我假设超时是“最后一个键后 3 秒”。如果您希望整个过程超时,我认为最简单的方法是获取当前时间,通过超时(即 get end_time)增加它,然后end_time - current_time以秒为超时传递到select()
  5. 我已将特定于 unix 的导入设为可选。不过,我不知道它是否能在 Windows 上正常工作。
于 2012-08-29T19:03:57.813 回答
1

好的。这个线程闲置了几年,但我花了一个小时探索这个(和相关的)线程以获得一个干净的解决方案。最后,我决定使用已经很好用的工具: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
于 2019-06-05T17:06:41.153 回答