2013-02-21 93 views
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() 
+1

您必須使用try/catch語句。看看http://stackoverflow.com/questions/5424716/python-how-to-check-if-input-is-a-number-given-that-input-always-returns-stri – user1929959 2013-02-21 21:50:40

回答

4

我建議不要使用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` 
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 
0

環繞聲明難熬嘗試/除

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

我應該注意到:有沒有辦法「防錯」的東西,很像子彈打樣不可能,一個足夠大的子彈將穿透任何東西,與編碼一樣。你所能做的就是編寫好的代碼。編碼沒有什麼是絕對的。

0

你不能使用ascii。例如,將字符串轉換爲數字值,然後忽略不在數字窗口內的結果,例如'if(c < = 47 and c> = 57):'。這應該可以阻止它崩潰。 我認爲:P

+0

不要回答除非你確定你的答案是正確的。此外,還應包含更多詳細信息,例如「if」的含義以及如果屬實,該怎麼辦。 – blm 2015-11-15 19:04:14

0

例外是舒適地路由和處理非平凡程序中的錯誤的方式。但一個清晰的概念有助於在程序不斷增長的時候不要隨意破解它。
(如捕內置ValueError遠或return ING /偶然繼續很快就會變得毛茸茸的。)

有誤差之間的主要區別造成

  • 由無效/奇用戶輸入
  • 通過錯誤
  • 受動態系統/環境限制。

分離,路由和處理這些錯誤的合理方法是:

  • (A)捕捉或潛在發生點附近很早就比較用戶輸入錯誤。立即作出反應,以進行簡單的恢復/重複。否則(打破了)轉換爲豐富例外可以被獲取,並進一步區分下來,或者在調用堆棧的底部(或默認處理程序sys.excepthook

  • (B)讓瀉而下的錯誤異常到調用堆棧的底部 - 未處理;或者可能啓動舒適的錯誤呈現和反饋操作。 (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()