在终端上清洁地处理用户输入而不会崩溃

时间:2013-02-21 21:48:02

标签: python python-3.x

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

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()

5 个答案:

答案 0 :(得分: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`

答案 1 :(得分:0)

使用exception handling

当有人给你无效输入时,Python不会崩溃,而是抛出异常。你可以捕获这些异常并处理它们,而不是让python退出程序。

在这种情况下,由于您只需要浮点数,所以您真的不应该使用eval();这将需要很多不同的输入,并会抛出很多不同的例外。

使用float()函数,如果输入错误,它只会抛出ValueError。然后捕获并显示错误消息:

try:
    pound = float(input("Enter the weight in pounds: "))
except ValueError:
    print('Not a valid number!')
    return

答案 2 :(得分: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()

我应该注意:没有办法“错误证明”的东西,就像防弹是不可能的,一个足够大的子弹将穿透任何东西,与编码相同。你所能做的就是编写好的代码。编码没有什么是绝对的。

答案 3 :(得分:0)

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

答案 4 :(得分:0)

例外是在非平凡程序中舒适地路由和处理错误的方法。但是一个明确的概念有助于在程序增长时不随意破解 (例如,抓住内置ValueError远离return /偶然的机会很快会变成毛茸茸的。)

导致错误之间存在主要区别

  • 通过无效/奇数用户输入
  • by bugs
  • 按动态系统/环境限制。

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

  • (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()