1

Pythonの練習のために、電卓のチュートリアルに取り組むことにしました。非常に基本的なことなので、ユーザーがゴミを入れた場合の例外処理を行うことにしました。プログラムの適切な使用は引き続き機能しますが、がらくたをパンチするとクラッシュし、次のように入力します。私のコードは次のとおりです。

loop = 1

choice = 0

while loop == 1:
    #print out the options you have
    print "Welcome to calculator.py"

    print "your options are:"

    print " "
    print "1) Addition"
    print "2) Subtraction"

    print "3) Multiplication"

    print "4) Division"
    print "5) Quit calculator.py"
    print " "

    choice = input("choose your option: ")
    try:
        if choice == 1:
            add1 = input("add this: ")
            add2= input("to this: ")
            print add1, "+", add2, "=", add1+ add2
        elif choice == 2:
            sub1 = input("Subtract this ")
            sub2 = input("from this")
            print sub1, "-", sub2, "=", sub1 - sub2
        elif choice == 3:
            mul1 = input("Multiply this: ")
            mul2 = input("with this: ")
            print mul1, "x", mul2, "=", mul1 * mul2
        elif choice == 4:
            div1 = input("Divide this: ")
            div2 = input("by this: ")
            if div2 == 0:
                print "Error! Cannot divide by zero!  You'll destroy the universe! ;)"
            else:

                print div1, "/", div2, "=", div1 * div2
        elif choice == 5:
            loop = 0
        else:
            print "%d is not valid input. Please enter 1, 2 ,3 ,4 or 5." % choice

    except ValueError:
        print "%r is not valid input.  Please enter 1, 2, 3, 4 or 5." % choice
    print "Thank you for using calculator.py!"

ここで有用な答えを見つけましたが、電卓プログラムのエラー処理変数ですが、エラー処理の数値は問題ありません。

なぜ私のコードが機能しなかったのか疑問に思いました。Pythonは関数で例外処理をしたいですか?それは私がそれから得ている雰囲気です。

4

3 に答える 3

5

Python 2(使用しているもの)inputでは、ユーザーが入力したものが何であれ、Pythonコードとして評価されます。このため、inputさまざまな例外が発生する可能性がありますが、まれにValueErrorです。

raw_input文字列を返すで入力を受け入れてから、期待されるタイプにキャストすることをお勧めします。入力が無効な場合は、ValueError: が発生します。

>>> x = int(raw_input("enter something: "))
enter something: sdjf
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: invalid literal for int() with base 10: 'sdjf'

注:Python 3ではinput、Python 2のセマンティクスを想定し、raw_input廃止raw_inputされます。

于 2012-06-01T15:03:45.490 に答える
2

あなたは捕まえていますValueError、それは捕まえるのは間違っています。

仕組みを見てみましょうinput()

>>> print input.__doc__
input([prompt]) -> value

Equivalent to eval(raw_input(prompt)).

つまり、インタラクティブなPythonセッションで入力したものを評価するのと同じように、その時点で入力した内容を評価します。たとえば、プロンプトでNameError入力しようとするとaがgarbagestring表示されます。同じ理由で、インタラクティブプロンプトでNameError入力しようとするとaが表示されます。garbagestring

>>> garbagestring
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'garbagestring' is not defined

これを行う正しい方法はraw_input()、の代わりにを使用してからinput()、返される文字列を整数に変換することです。

>>> raw_input('Prompt: ')
Prompt: garbagestring
'garbagestring'
>>> int(raw_input('Prompt: '))
Prompt: garbagestring
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: invalid literal for int() with base 10: 'garbagestring'
>>> int(raw_input('Prompt: '))
Prompt: 45
45

これにより、使用時にエラーが検出されます。

一般に、漠然とのように見えることは行わないようにする必要があることに注意してくださいeval()。一般に、それがなくても必要なことは何でも達成できますeval()。信頼できない文字列を使用すると、セキュリティ上のリスクが生じる可能性があります。たとえば、import osスクリプトの先頭に(かなり一般的なインポート)を追加すると、次のことができます。

Multiply this: os.listdir('/')
with this: 0
['bin', 'cygdrive', 'dev', 'etc', 'home', 'lib', 'tmp', 'usr', 'var', 'proc'] x 0 = []
Thank you for using calculator.py!

ファイルの読み取り、重要なフォルダの削除なども同じように簡単にできました。

于 2012-06-01T15:14:59.103 に答える
0

inputeval()ユーザーの入力を行い、input基本的にはeval(raw_input(prompt))

したがって、を入力loopすると失敗することはなく、実際にはに設定さchoice1ます。

を入力aすると、評価されてNameError例外が発生します。

入力1 + 1すると差し引かれます。

私はあなたがその考えを理解することを望みます。

于 2012-06-01T15:19:36.327 に答える