input函式出現的問題(Python)

夢書發表於2013-10-17

參考書<A Learner's Guide to Programming Using the Python Language>,寫下如下的程式:

 1 # coding=utf-8
 2 # 以上是為了能在文中新增中文的註釋
 3 
 4 def save_transaction(price, credit_card, description):
 5     file = open("transaction.txt", "a")
 6     file.write("%s%07d%16s\n" % (credit_card, price, description))
 7     file.close()
 8     
 9 items = ["DONUT","LATTE","FILTER","MUFFIN"]
10 prices = [1.50, 2.0, 1.80, 1.20]
11 running = True
12 
13 while running:
14     option = 1
15     for choice in items:
16         print(str(option) + "." + choice)
17         option = option + 1
18         
19     print(str(option) + ".Quit")
20     
21     choice = int(input("Choose an option: "))
22     if option == choice:
23         running = False
24     else:
25         #用input的話,如果是以0開始的字串的話,就會報錯
26         credit_card = input("Credit card number: ")
27         while len(credit_card) != 16 :
28             credit_card = input("the length of credit card number must be equal to 16. Please input Credit card number again: ")
29         save_transaction(prices[choice-1]*100, credit_card, items[choice-1])

但是,在執行到第26行的時候,如果輸入“0987648900804387”時,會出現如下的錯誤:

Traceback (most recent call last):
  File "transaction.py", line 26, in <module>
    credit_card = input("Credit card number: ")
  File "<string>", line 1
    0987648900804387
                  ^
SyntaxError: invalid token

上網查了下,注意到一個細節:

input其實是通過raw_input來實現的,原理很簡單,就下面一行程式碼:[參考 http://www.cnblogs.com/linlu11/archive/2009/11/25/1610830.html]

def input(prompt):
    return (eval(raw_input(prompt)))

那麼,簡單寫了測試函式:

>>> eval("0123")
83
>>> eval("0987")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<string>", line 1
    0987
      ^
SyntaxError: invalid token

>>> eval("0x9d")
157
>>> eval("0x9h")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<string>", line 1
    0x9h
      ^
SyntaxError: unexpected EOF while parsing

可見,在input函式中,呼叫eval時候,會根據字串中的第一個或者前2個字元來判斷字串對應是8進位制還是16進位制的,

如果是0,就是按照8進位制來處理:所以上面的輸入是 0987648900804387 非法的,不是一個有效的8進位制數;

如果是0x,就按照16進位制來處理,所以0x9h也是非法的。

因此,原程式中的第26行到28行,可以換成:

1         credit_card = raw_input("Credit card number: ")
2         while len(credit_card) != 16 :
3             credit_card = raw_input("the length of credit card number must be equal to 16. Please input Credit card number again: ")

 

相關文章