我正在编写一个接受用户输入的程序。

#note: Python 2.7 users should use `raw_input`, the equivalent of 3.X's `input`
age = int(input("Please enter your age: "))
if age >= 18: 
    print("You are able to vote in the United States!")
else:
    print("You are not able to vote in the United States.")

只要用户输入有意义的数据,程序就能正常工作。

Please enter your age: 23
You are able to vote in the United States!

但如果用户输入无效数据,则失败:

Please enter your age: dickety six
Traceback (most recent call last):
  File "canyouvote.py", line 1, in <module>
    age = int(input("Please enter your age: "))
ValueError: invalid literal for int() with base 10: 'dickety six'

而不是崩溃,我希望程序再次要求输入。是这样的:

Please enter your age: dickety six
Sorry, I didn't understand that.
Please enter your age: 26
You are able to vote in the United States!

我如何要求有效输入而不是崩溃或接受无效值(例如-1)?


当前回答

使用自定义ValidationError和(可选的)整数输入范围验证的输入验证的另一个解决方案:

class ValidationError(ValueError): 
    """Special validation error - its message is supposed to be printed"""
    pass

def RangeValidator(text,num,r):
    """Generic validator - raises 'text' as ValidationError if 'num' not in range 'r'."""
    if num in r:
        return num
    raise ValidationError(text)

def ValidCol(c): 
    """Specialized column validator providing text and range."""
    return RangeValidator("Columns must be in the range of 0 to 3 (inclusive)", 
                          c, range(4))

def ValidRow(r): 
    """Specialized row validator providing text and range."""
    return RangeValidator("Rows must be in the range of 5 to 15(exclusive)",
                          r, range(5,15))

用法:

def GetInt(text, validator=None):
    """Aks user for integer input until a valid integer is given. If provided, 
    a 'validator' function takes the integer and either raises a 
    ValidationError to be printed or returns the valid number. 
    Non integers display a simple error message."""
    print()
    while True:
        n = input(text)
        try:
            n = int(n)

            return n if validator is None else validator(n)

        except ValueError as ve:
            # prints ValidationErrors directly - else generic message:
            if isinstance(ve, ValidationError):
                print(ve)
            else:
                print("Invalid input: ", n)


column = GetInt("Pleased enter column: ", ValidCol)
row = GetInt("Pleased enter row: ", ValidRow)
print( row, column)

输出:

Pleased enter column: 22
Columns must be in the range of 0 to 3 (inclusive)
Pleased enter column: -2
Columns must be in the range of 0 to 3 (inclusive)
Pleased enter column: 2
Pleased enter row: a
Invalid input:  a
Pleased enter row: 72
Rows must be in the range of 5 to 15(exclusive)
Pleased enter row: 9  

9, 2

其他回答

好问题!您可以尝试以下代码。=)

这段代码使用ast.literal_eval()来查找输入的数据类型(age)。然后按照以下算法:

请用户输入年龄。 1.1. 如果age为float或int数据类型: 检查年龄>是否=18。如果age>=18,打印相应的输出并退出。 检查0<年龄<18。如果0<age<18,打印适当的输出并退出。 如果age<=0,请用户再次输入age的有效数字(即返回步骤1)。 1.2. 如果age不是float或int数据类型,则要求用户再次输入她/他的年龄(即返回第1步)。

这是代码。

from ast import literal_eval

''' This function is used to identify the data type of input data.'''
def input_type(input_data):
    try:
        return type(literal_eval(input_data))
    except (ValueError, SyntaxError):
        return str

flag = True

while(flag):
    age = raw_input("Please enter your age: ")

    if input_type(age)==float or input_type(age)==int:
        if eval(age)>=18: 
            print("You are able to vote in the United States!") 
            flag = False 
        elif eval(age)>0 and eval(age)<18: 
            print("You are not able to vote in the United States.") 
            flag = False
        else: print("Please enter a valid number as your age.")

    else: print("Sorry, I didn't understand that.") 

使用“while”语句,直到用户输入一个真值,如果输入值不是一个数字或它是一个空值跳过它,并尝试再次询问,等等。 举例来说,我试图真正地回答你的问题。如果我们假设我们的年龄在1到150之间,那么输入值被接受,否则它是一个错误的值。 对于终止程序,用户可以使用0键并输入它作为一个值。

注意:阅读代码顶部的注释。

# If your input value is only a number then use "Value.isdigit() == False".
# If you need an input that is a text, you should remove "Value.isdigit() == False".
def Input(Message):
    Value = None
    while Value == None or Value.isdigit() == False:
        try:        
            Value = str(input(Message)).strip()
        except Exception:
            Value = None
    return Value

# Example:
age = 0
# If we suppose that our age is between 1 and 150 then input value accepted,
# else it's a wrong value.
while age <=0 or age >150:
    age = int(Input("Please enter your age: "))
    # For terminating program, the user can use 0 key and enter it as an a value.
    if age == 0:
        print("Terminating ...")
        exit(0)
        
if age >= 18 and age <=150: 
    print("You are able to vote in the United States!")
else:
    print("You are not able to vote in the United States.")

我是Unix哲学“只做一件事并把它做好”的忠实粉丝。捕获用户输入并验证它是两个独立的步骤:

使用get_input提示用户输入,直到输入成功 使用可以传递给get_input的验证器函数进行验证

它可以保持简单如(Python 3.8+,使用walrus操作符):

def get_input(
    prompt="Enter a value: ",
    validator=lambda x: True,
    error_message="Invalid input. Please try again.",
):
    while not validator(value := input(prompt)):
        print(error_message)
    return value

def is_positive_int(value):
    try:
        return int(value) >= 0
    except ValueError:
        return False

if __name__ == "__main__":
    val = get_input("Give a positive number: ", is_positive_int)
    print(f"OK, thanks for {val}")

示例运行:

Give a positive number: -5
Invalid input. Please try again.
Give a positive number: asdf
Invalid input. Please try again.
Give a positive number:
Invalid input. Please try again.
Give a positive number: 42
OK, thanks for 42

在Python < 3.8中,你可以像这样使用get_input:

def get_input(
    prompt="Enter a value: ",
    validator=lambda x: True,
    error_message="Invalid input. Please try again.",
):
    while True:
        value = input(prompt)
        if validator(value):
            return value
        print(error_message)

您还可以在终止应用程序之前处理KeyboardInterrupt并打印友好的退出消息。如果需要,可以使用计数器限制允许的重试次数。

您总是可以应用简单的if-else逻辑,并在for循环的同时向代码中添加一个if逻辑。

while True:
     age = int(input("Please enter your age: "))
     if (age >= 18)  : 
         print("You are able to vote in the United States!")
     if (age < 18) & (age > 0):
         print("You are not able to vote in the United States.")
     else:
         print("Wrong characters, the input must be numeric")
         continue

这将是一个无限的厕所,你将被要求进入一个无限的时代。

您可以尝试将其转换为整数,但如果不成功,请用户重复。

while True:
    age = input('Please enter your age: ')
    try:
        age_int = int(age)
        if age_int >= 18:
            print('You can vote in the United States!')
        else:
            print('You cannot vote in the United States.')
        break
    except:
        print('Please enter a meaningful answer.')
        

只要用户没有输入有意义的答案,while循环就会运行,但如果有意义就会中断。