简体   繁体   English

如何在Python 2.7中将用户输入限制为特定的整数,并跟踪异常?

[英]How do I limit user input to specific integers, and keep track of exceptions, in Python 2.7?

EDIT: The suggested duplicate is incredibly helpful in regards to basic input validation. 编辑:建议的重复对于基本输入验证非常有用。 While it does cover a lot, my specific problem (failing to assign int(evaluation) to a variable) is only explicitly addressed here. 尽管确实涵盖了很多内容,但我的特定问题(未能将int(evaluation)分配给变量)仅在此处明确解决。 I'm marking this separately in case anyone else has made a similarly silly mistake :) 如果其他人犯了类似的愚蠢错误,则我将单独标记它:)

I've spent the last few weeks playing with Python 2.7 and having a lot of fun. 在过去的几周中,我一直在使用Python 2.7玩耍,并且玩得很开心。 To learn more about while loops, I've created a small script which asks the user for an integer between 1 and 10. 要了解有关while循环的更多信息,我创建了一个小脚本,该脚本要求用户输入1到10之间的整数。

My goal is to then be able to respond to cases in which the user responds with unexpected input, like a non-integer, or an integer outside the specified range. 我的目标是能够响应用户使用意外输入(例如非整数或超出指定范围的整数)做出响应的情况。 I've been able to fix a lot of my issues with help from other StackOverflow threads, but now I'm stumped. 在其他StackOverflow线程的帮助下,我已经能够解决很多问题,但是现在我很困惑。

First, I created a variable, idiocy , to keep track of exceptions. 首先,我创建了一个变量idiocy ,以跟踪异常。 (The script is supposed to be sassy, but until I get it working, I'm the one it's making fun of.) (该脚本本来应该很活泼,但是直到我能正常工作为止, 我是那个正在取笑的人。)

idiocy = 0

while 1:
    evaluation = raw_input("> ")
    try:
        int(evaluation)
        if evaluation < 1 or evaluation > 10:
            raise AssertionError
    except ValueError:
        idiocy += 1
        print "\nEnter an INTEGER, dirtbag.\n"
    except AssertionError:
        idiocy += 1
        print "\nI said between 1 and 10, moron.\n"
    else:
        if idiocy == 0:
            print "\nOkay, processing..."
        else:
            print "\nDid we finally figure out how to follow instructions?"
            print "Okay, processing..."
        break

As you can see, I'm trying to handle two different errors -- a ValueError for the input type, and an AssertionError for the integer range -- and keep track of how many times they're raised. 如您所见,我正在尝试处理两个不同的错误-输入类型的ValueError和整数范围的AssertionError并跟踪它们引发了多少次。 (Really, I only care about knowing whether or not they've been raised at least once; that's all I need to insult the user.) (真的,我只关心知道它们是否至少被提升过一次;这就是我侮辱用户的全部。)

Anyways, when I run the script in its current form, the error response works just fine ('dirtbag' for non-integers, 'moron' for out-of-range). 无论如何,当我以当前形式运行脚本时,错误响应就可以正常工作(对于非整数,“ dirtbag”为“ dirtbag”,对于超出范围,则为“ moron”)。 The problem is that even when I input a valid integer, I still get an out-of-range AssertionError . 问题是,即使我输入了有效的整数,我仍然会收到超出范围的AssertionError

I suspect that my issue has to do with my while logic, but I'm not sure what to do. 我怀疑我的问题与我的while逻辑有关,但我不确定该怎么做。 I've added a break here or there but that doesn't seem to help. 我在这里或那里添加了一个break ,但这似乎无济于事。 Any suggestions or blatant errors? 有什么建议或明显的错误吗? Again, total Python beginner here, so I'm half winging it. 同样,这里是Python的新手,所以我将其付诸实践。

//If anyone has simpler, cleaner, or prettier ways to do this, feel free to let me know too. //如果有人有更简单,更清洁或更漂亮的方法来进行此操作,请随时告诉我。 I'm here to learn! 我在这里学习!

Your problem is you're not saving the int version of evaluation to evaluation like this: 你的问题是你不保存int版本evaluation ,以evaluation是这样的:

idiocy = 0

while 1:
    evaluation = raw_input("> ")
    try:
        evaluation = int(evaluation) <--- here
        if evaluation < 1 or evaluation > 10:
            raise AssertionError
    except ValueError:
        idiocy += 1
        print "\nEnter an INTEGER, dirtbag.\n"
    except AssertionError:
        idiocy += 1
        print "\nI said between 1 and 10, moron.\n"
    else:
        if idiocy == 0:
            print "\nDid we finally figure out how to follow instructions?"
            print "Okay, processing..."
        else:
            print "\nOkay, processing..."

If you wanted to track the types of exceptions raised, you could use collections.Counter for idiocy and change the code like this: 如果要跟踪引发的异常类型,则可以使用collections.Counter进行idiocy并更改如下代码:

from collections import Counter

idiocy = Counter()

while 1:
    evaluation = raw_input("> ")
    try:
        evaluation = int(evaluation)
        if evaluation < 1 or evaluation > 10:
            raise AssertionError
    except ValueError as e:
        idiocy[e.__class__] += 1 
        print "\nEnter an INTEGER, dirtbag.\n"
    except AssertionError as e:
        idiocy[e.__class__] += 1
        print "\nI said between 1 and 10, moron.\n"
    else:
        if idiocy == 0:
            print "\nDid we finally figure out how to follow instructions?"
            print "Okay, processing..."
        else:
            print "\nOkay, processing..."

>>> idiocy
Counter({AssertionError: 2, ValueError: 3})

And you can access the error counts by key like idiocy[AssertionError] 您可以通过idiocy[AssertionError]类的键来访问错误计数

You have int(evalutation) , but you're not assigning it to anything. 您有int(evalutation) ,但没有将其分配给任何东西。

Try 尝试

try:
    evaluation = int(evaluation)
    assert 0 < evaluation < 10
except ValueError:
    ...
except AssertionError:

Your range test can be refactored as 您的范围测试可以重构为

assert 1 <= evaluation <= 10

You could keep your insults in a dictionary 你可以把侮辱记在字典里

insults = {AssertionError : "\nI said between 1 and 10, moron.\n",
           ValueError : "\nEnter an INTEGER, dirtbag.\n"
           }

And write the try/except like this 然后像这样写try / except

try:
    ...
except (AssertionError, ValueError) as e:
    print(insults[type(e)])

When you change the user input to an int, you need to assign it to something 将用户输入更改为int时,需要将其分配给某些内容

evaluation = int(evaluation)

assert was meant for debugging - you are using it incorrectly. assert是用于调试的-您未正确使用它。

  • You should use TypeError for non-integer repsonses - the type is wrong. 您应该将TypeError用于非整数响应-类型错误。
  • You use ValueError for responses outside of a range - the value is wrong 您将ValueError用于超出范围的响应-值错误

In your code: int(evaluation) is not typecasting evaluation variable to int type. 在您的代码中: int(evaluation)不是将评估变量类型转换为int类型。 The output is: 输出为:

> 2
<type 'str'>
I said between 1 and 10, moron.

Try this: 尝试这个:

idiocy = 0

while 1:
    try:
        evaluation = int(raw_input("> "))
        if evaluation < 1 or evaluation > 10:
            raise AssertionError
    except ValueError:
        idiocy += 1
        print "\nEnter an INTEGER, dirtbag.\n"
    except AssertionError:
        idiocy += 1
        print "\nI said between 1 and 10, moron.\n"
    else:
        if idiocy == 0:
            print "\nOkay, processing..."
        else:
            print "\nDid we finally figure out how to follow instructions?"
            print "Okay, processing..."
        break

By the way you can use tuple to store all your exceptions. 顺便说一下,您可以使用元组来存储所有异常。 Example: 例:

idiocy = 0

all_exceptions = (ValueError, AssertionError)
while 1:
    try:
        evaluation = int(raw_input("> "))
        if evaluation < 1 or evaluation > 10:
            raise AssertionError("\nI said between 1 and 10, moron.\n")
    except all_exceptions as e:
        idiocy += 1
        print str(e)
    else:
        if idiocy == 0:
            print "\nOkay, processing..."
        else:
            print "\nDid we finally figure out how to follow instructions?"
            print "Okay, processing..."
        break

Hope it helps. 希望能帮助到你。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM