1

我有这个简单的项目要做。这是我到目前为止的代码,它工作得很好。但是,如果有人输入字母或未知符号,程序就会崩溃。如果输入了错误的内容,我怎样才能证明错误并显示或打印消息?

def excercise5():

    print("Programming Excercise 5")
    print("This program calculates the cost of an order.")
    pound = eval(input("Enter the weight in pounds: "))
    shippingCost = (0.86 * pound) + 1.50
    coffee = (10.50 * pound) + shippingCost
    if pound == 1:
        print(pound,"pound of coffee costs $", coffee)
    else:
        print(pound,"pounds of coffee costs $", coffee)
    print()

excercise5()
4

5 回答 5

5

我建议不要使用eval. 从安全的角度来看,这并不好。只需对所需类型进行显式转换:

pound = float(input("Enter the weight in pounds: "))

处理无效输入:

try:
    pound = float(input("Enter the weight in pounds: "))
except ValueError:
    print('Invalid input.')
    return
# the rest of the code

或者:

try:
    pound = float(input("Enter the weight in pounds: "))
except ValueError:
    print('Invalid input.')
else:
    # the rest of the code

您还可以将输入包装在一个无限循环中,该循环将在成功转换时终止:

while True:
    try:
        pound = float(input("Enter the weight in pounds: "))
    except ValueError:
        print('Invalid input. Try again.')
    else:
        break
# do the rest with `pound`
于 2013-02-21T21:52:01.303 回答
0

使用异常处理

当有人为您提供无效输入时,Python 不会崩溃,而是会引发异常。您可以捕获此类异常并处理它们,而不是让 python 退出程序。

在这种情况下,由于您只需要一个浮点数,因此您真的不应该使用eval(); 这将需要很多不同的输入,并会引发很多不同的异常。

请改用该函数,如果您输入不正确float(),它只会抛出 a 。ValueError然后抓住它并显示一条错误消息:

try:
    pound = float(input("Enter the weight in pounds: "))
except ValueError:
    print('Not a valid number!')
    return
于 2013-02-21T21:52:55.413 回答
0

用 try/except 包围语句

def excercise5():
    print("Programming Excercise 5")
    print("This program calculates the cost of an order.")
    pound = eval(input("Enter the weight in pounds: "))
    try:
        shippingCost = (0.86 * pound) + 1.50
        coffee = (10.50 * pound) + shippingCost
        if pound == 1:
            print(pound,"pound of coffee costs $", coffee)
        else:
            print(pound,"pounds of coffee costs $", coffee)
    except ValueError:
        print("Please Enter a valid number")
    print()

我应该注意:没有办法“防错”某些东西,就像防弹是不可能的,足够大的子弹会穿透任何东西,编码也是如此。你所能做的就是写出好的代码。编码中没有什么是绝对的。

于 2013-02-21T21:54:00.593 回答
0

你能不使用ascii吗?例如,将字符串转换为数值,然后忽略不在数值窗口中的结果,例如'if (c <= 47 and c >= 57):'。这应该会阻止它崩溃。我认为:P

于 2015-11-15T18:41:03.863 回答
0

异常是在非平凡程序中轻松路由和处理错误的方法。但是一个清晰的概念有助于在程序增长时不要随意破解。(例如,在很远的地方
捕捉内置函数或ing / continue 会很快变得毛茸茸。)ValueErrorreturn

引起的错误之间的主要区别是

  • 通过无效/奇怪的用户输入
  • 通过错误
  • 受动态系统/环境限制。

分离、路由和处理这些错误的合理方法是:

  • (A) 在可能发生的点附近很早就发现或比较用户输入错误。立即做出反应以进行简单的恢复/重复。否则(用于中断)转换为丰富的异常,该异常可以在调用堆栈的底部或底部(或默认处理程序sys.excepthook)进一步捕获和区分

  • (B) 让 bug 异常崩溃到调用堆栈的底部——未处理;或者可能启动舒适的错误演示和反馈操作。

  • (C) 对于系统环境错误,在 (A) 和 (B) 之间选择一种方法,具体取决于您希望在当前开发阶段出现多少上下文、详细信息和舒适信息。

这样,这可以成为您示例中面向用户的错误处理的可扩展模式:

# Shows scalable user oriented error handling

import sys, traceback

DEBUG = 0

class UserInputError(Exception):
    pass

def excercise5():

    print("Programming Excercise 5")
    print("This program calculates the cost of an order.")

    # NOTE: eval() and input() was dangerous
    s = input("Enter the weight in pounds: ")
    try:        
        pound = float(s) 
    except ValueError as ev:
        raise UserInputError("Number required for weight, not %r" % s, ev)
    if pound < 0:
        raise UserInputError("Positive weight required, not %r" % pound)

    shippingCost = (0.86 * pound) + 1.50
    coffee = (10.50 * pound) + shippingCost
    if pound == 1:
        print(pound,"pound of coffee costs $", coffee)
    else:
        print(pound,"pounds of coffee costs $", coffee)
    print()

if __name__ == '__main__':
    try:
        excercise5()
    except UserInputError as ev:
        print("User input error (please retry):")
        print(" ", ev.args[0])
        if DEBUG and len(ev.args) > 1:
            print("  EXC:", ev.args[1], file=sys.stderr)
    except (EnvironmentError, KeyboardInterrupt) as ev:
        print("Execution error happend:")
        print(" ", traceback.format_exception_only(ev.__class__, ev)[0])
    except Exception:
        print("Please report this bug:")
        traceback.print_exc()
于 2016-08-26T10:53:32.433 回答