3

假设我们在 python3.3 和多平台(Linux 和 WINdow)上,如果我执行以下操作:

>>> eval(input("enter a percent from 1-100"))

我得到:

enter a percent from 1-100: (Terminal is Waiting for user prompt) 

我希望它显示:

enter a percent from 1-100: (waiting for user prompt)  %

如何%在括号后显示?

4

2 回答 2

3

如果我理解您的问题,您希望能够编写包含%符号字符的提示,但将用户的光标放在符号的左侧,如下所示:

Enter a percent from 1-100:     %
                            ^ cursor is here

对此没有通用的解决方案,因为基本的文本 IO 通常面向没有明确定义的交互的输入和输出流。有些方法在某些情况下有效,但在其他情况下无效,但我不确定是否有任何方法可以在任何地方都有效(除了编写 GUI)。

我的一个建议是在提示中包含 ASCII(和 unicode)退格字符'\b'(或'\x08')。在某些控制台上,这会将光标向左移动每个退格键一个字符。因此,上面的提示可以通过以下方式生成:

input("Enter a percent from 1-100:     %\b\b\b\b\b")

这在我从 Windows CMD.exeshell 运行 Python 时有效,但在我在 IDLE 中运行时无效('\x08'字符显示为一个盒子,中间有一个小圆圈)。不过这有点粗略,因为它不能阻止用户输入的字符多于之前的空格%(这将被输入的第五个字符覆盖)。

另一个可能更健壮(但不是跨平台,唉)的解决方案是使用cursesmodule。我没有足够的知识来建议代码,但应该可以让它做你想做的事情(甚至控制一些事情,比如阻止用户输入三个以上的字符,或者移动%标志以正确对齐的值任何长度)。

最后一件事:我强烈建议您不要evalinput通话时使用。如果您期望(并且需要)一个整数值,请使用int(input()). 如果你可能得到一个整数,但也可能得到其他类型的值,请使用多行来测试你得到了什么:

def get_val():
    str_val = input()
    try:
        return int(str_val) # handle numbers like 1, 23232, etc.
    except ValueError:
        pass

    try:
        return float(str_val) # handles 23.5 and -3e-3 (but beware, also "nan" and "inf")
    except ValueError:
        pass

    try:
        return make_some_other_value(str_val) # whatever you want
    except ValueError:
        pass

    return str_val # give up and return the string
于 2013-10-25T03:47:44.807 回答
2

这是使用getch包的替代方法。input我们将自己滚动而不是使用。

import string
import sys
try:
    from msvcrt import getch
except ImportError:
    from getch import getch


def char_valid(char):
    """Do whatever validation you need here."""
    return char in string.ascii_letters or char in string.digits


def char_bkspace(char):
    """Matches backspace and delete."""
    return char in ['\x08', '\x7f']

message_pre = 'enter a percent from 1-100'
message_post = '%'
user_input = ''
while True:
    sys.stdout.write('\r{0} {1} {2}'.format(message_pre, user_input, message_post))
    char = getch()
    if char_bkspace(char):
        user_input = user_input[:-1]
    elif char_valid(char):
        user_input += char
    else:
        break

print('\nyour message was', user_input)

while这让用户使用 . 在循环中一次输入一个字符getch。通过使用sys.stdout.write('\r...'),我们可以避免换行并不断覆盖前一行。

这有一个问题,如果你退格,多个%将是可见的,因为新行没有完全覆盖前一行。这可以通过用空格填充字符串来解决。

于 2013-10-25T05:26:38.263 回答