要求用户输入直到他们给出有效的响应 [英] Asking the user for input until they give a valid response

查看:32
本文介绍了要求用户输入直到他们给出有效的响应的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am writing a program that accepts an input from the user.

#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.")

只要用户输入有意义的数据,程序就会按预期工作.

The program works as expected as long as the the user enters meaningful data.

C:PythonProjects> canyouvote.py
Please enter your age: 23
You are able to vote in the United States!

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

But it fails if the user enters invalid data:

C:PythonProjects> canyouvote.py
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'

与其崩溃,我希望程序再次请求输入.像这样:

Instead of crashing, I would like the program to ask for the input again. Like this:

C:PythonProjects> canyouvote.py
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!

如何让程序在输入无意义数据时要求有效输入而不是崩溃?

How can I make the program ask for valid inputs instead of crashing when non-sensical data is entered?

我如何拒绝像 -1 这样的值,它是一个有效的 int,但在这种情况下是荒谬的?

How can I reject values like -1, which is a valid int, but nonsensical in this context?

推荐答案

最简单的方法是将 input 方法放入 while 循环中.使用 continue 当你输入错误时,break 当你满意时退出循环.

The simplest way to accomplish this is to put the input method in a while loop. Use continue when you get bad input, and break out of the loop when you're satisfied.

使用 tryexcept 检测用户何时输入无法解析的数据.

Use try and except to detect when the user enters data that can't be parsed.

while True:
    try:
        # Note: Python 2.x users should use raw_input, the equivalent of 3.x's input
        age = int(input("Please enter your age: "))
    except ValueError:
        print("Sorry, I didn't understand that.")
        #better try again... Return to the start of the loop
        continue
    else:
        #age was successfully parsed!
        #we're ready to exit the loop.
        break
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.")

实施您自己的验证规则

如果要拒绝 Python 可以成功解析的值,可以添加自己的验证逻辑.

Implementing Your Own Validation Rules

If you want to reject values that Python can successfully parse, you can add your own validation logic.

while True:
    data = input("Please enter a loud message (must be all caps): ")
    if not data.isupper():
        print("Sorry, your response was not loud enough.")
        continue
    else:
        #we're happy with the value given.
        #we're ready to exit the loop.
        break

while True:
    data = input("Pick an answer from A to D:")
    if data.lower() not in ('a', 'b', 'c', 'd'):
        print("Not an appropriate choice.")
    else:
        break

结合异常处理和自定义验证

上述两种技术可以合并为一个循环.

Combining Exception Handling and Custom Validation

Both of the above techniques can be combined into one loop.

while True:
    try:
        age = int(input("Please enter your age: "))
    except ValueError:
        print("Sorry, I didn't understand that.")
        continue

    if age < 0:
        print("Sorry, your response must not be negative.")
        continue
    else:
        #age was successfully parsed, and we're happy with its value.
        #we're ready to exit the loop.
        break
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.")

将其全部封装在一个函数中

如果您需要向用户询问许多不同的值,将这段代码放在一个函数中可能会很有用,这样您就不必每次都重新输入.

Encapsulating it All in a Function

If you need to ask your user for a lot of different values, it might be useful to put this code in a function, so you don't have to retype it every time.

def get_non_negative_int(prompt):
    while True:
        try:
            value = int(input(prompt))
        except ValueError:
            print("Sorry, I didn't understand that.")
            continue

        if value < 0:
            print("Sorry, your response must not be negative.")
            continue
        else:
            break
    return value

age = get_non_negative_int("Please enter your age: ")
kids = get_non_negative_int("Please enter the number of children you have: ")
salary = get_non_negative_int("Please enter your yearly earnings, in dollars: ")

将它们放在一起

你可以扩展这个想法来制作一个非常通用的输入函数:

Putting It All Together

You can extend this idea to make a very generic input function:

def sanitised_input(prompt, type_=None, min_=None, max_=None, range_=None):
    if min_ is not None and max_ is not None and max_ < min_:
        raise ValueError("min_ must be less than or equal to max_.")
    while True:
        ui = input(prompt)
        if type_ is not None:
            try:
                ui = type_(ui)
            except ValueError:
                print("Input type must be {0}.".format(type_.__name__))
                continue
        if max_ is not None and ui > max_:
            print("Input must be less than or equal to {0}.".format(max_))
        elif min_ is not None and ui < min_:
            print("Input must be greater than or equal to {0}.".format(min_))
        elif range_ is not None and ui not in range_:
            if isinstance(range_, range):
                template = "Input must be between {0.start} and {0.stop}."
                print(template.format(range_))
            else:
                template = "Input must be {0}."
                if len(range_) == 1:
                    print(template.format(*range_))
                else:
                    expected = " or ".join((
                        ", ".join(str(x) for x in range_[:-1]),
                        str(range_[-1])
                    ))
                    print(template.format(expected))
        else:
            return ui

使用如:

age = sanitised_input("Enter your age: ", int, 1, 101)
answer = sanitised_input("Enter your answer: ", str.lower, range_=('a', 'b', 'c', 'd'))

常见的陷阱,以及为什么要避免它们

冗余input语句的冗余使用

此方法有效,但通常被认为风格不佳:

Common Pitfalls, and Why you Should Avoid Them

The Redundant Use of Redundant input Statements

This method works but is generally considered poor style:

data = input("Please enter a loud message (must be all caps): ")
while not data.isupper():
    print("Sorry, your response was not loud enough.")
    data = input("Please enter a loud message (must be all caps): ")

它最初可能看起来很有吸引力,因为它比 while True 方法短,但它违反了 不要重复自己 软件开发的原则.这会增加系统中出现错误的可能性.如果您想通过将 input 更改为 raw_input 来向后移植到 2.7,但不小心只更改了上面的第一个 input 怎么办?这是一个等待发生的 SyntaxError.

It might look attractive initially because it's shorter than the while True method, but it violates the Don't Repeat Yourself principle of software development. This increases the likelihood of bugs in your system. What if you want to backport to 2.7 by changing input to raw_input, but accidentally change only the first input above? It's a SyntaxError just waiting to happen.

如果您刚刚了解递归,您可能会想在 get_non_negative_int 中使用它,以便处理 while 循环.

If you've just learned about recursion, you might be tempted to use it in get_non_negative_int so you can dispose of the while loop.

def get_non_negative_int(prompt):
    try:
        value = int(input(prompt))
    except ValueError:
        print("Sorry, I didn't understand that.")
        return get_non_negative_int(prompt)

    if value < 0:
        print("Sorry, your response must not be negative.")
        return get_non_negative_int(prompt)
    else:
        return value

这在大多数情况下似乎工作正常,但如果用户输入无效数据的次数足够多,脚本将终止并显示 RuntimeError: maximum recursion depth exceeded.你可能认为没有一个傻瓜会连续犯1000个错误",但你低估了傻瓜的聪明才智!

This appears to work fine most of the time, but if the user enters invalid data enough times, the script will terminate with a RuntimeError: maximum recursion depth exceeded. You may think "no fool would make 1000 mistakes in a row", but you're underestimating the ingenuity of fools!

这篇关于要求用户输入直到他们给出有效的响应的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆