2015-10-13 7 views
8

int("1.7")と入力すると、Pythonはエラー(具体的にはValueError)を返します。私はint(float("1.7"))で整数に変換できることを知っています。私は最初のメソッドがエラーを返す理由を知りたいです。 documentationから"1.7"を浮動小数点に変換せずに整数に直接変換できないのはなぜですか?

+1

整数と浮動小数点数は、コンピュータによって異なる動作をします。同じ目的のためにそれらを混在させることはまれです。したがって、Pythonの動作はエラーを防ぎます。 – Nayuki

+1

私はintがfloatとは違って文字列を扱うので、浮動小数点数を切り捨てます...しかし、数字の文字列をチェックします(両端の空白は大丈夫です)。 –

+0

Pythonは微妙なバグを防ぎます。想像してみてください。あなたはボブに年齢を尋ねます。 Bobは「私は来月18歳に向かいます」と考えて、あなたのコードが期待していなかった17.9を入力します。 0.9を投げ捨てたいのですか、エラーを通知してBobが入力を修正したり、コードを修正したりしますか? Pythonのモットーの1つは、「明示的に沈黙されない限り、エラーは黙ってはいけません。あいまいさに直面して、推測する誘惑を拒否します」。あなたの機能はその指針に反するので、Pythonはそれをしません。もっと知恵の言葉を聞くには、「これをインポート」と入力してください。 –

答えて

9

xは数字でないか、または塩基が与えられた場合、xは基数ベースでリテラル整数を表す文字列またはUnicodeオブジェクトでなければならない場合...

明らかに、"1.7"は、基数の整数リテラルを表すものではありません。

あなたはのpythonのdevの者は、基数ベースの整数リテラルに自分自身を制限することを決めた理由は、そこに理由の可能性無限の数があり、あなたはグイドらに依頼する必要があると思いを知りたい場合。確かに知っている。 1つは、導入の容易さと効率性です。

  1. が整数ことができますようにpythonでは動作しません

残念ながら整数にfloatとして

  • TRUNCATEを数の解釈:あなたは彼らがそれを実装するためとして、それは簡単だろうと思うかもしれません任意の精度を持ち、浮動小数点はできません。特殊なケーシングの大きな数字は、一般的なケースでは非効率につながる可能性があります。さらに

    、あなたがint(float(...))に行う強制的に明快で追加の利点を持っている - それはどのような入力文字列それがより明確になり、おそらくは、他の場所でのデバッグに役立つことができたように見えます。実際には、int"1.7"のような文字列を受け入れる場合でも、コードの明瞭性を高めるためには、とにかくint(float("1.7"))と書くことをお勧めします。

    いくつかの検証を前提とします。他の言語はこれをスキップします。 ruby'1e6'.to_iと評価され、1と表示されます。最初の非整数文字での解析が停止するためです。そのように見える楽しいバグにつながる可能性があります...

  • +2

    私は、intが任意の精度であることとは関係ないと思います。 Rubyでは、 "" 1.7 ".to_i' ==' 1'です。彼らは最初の無効な文字の解析を停止します。私はそれがバグを見つけにくいのを防ぐのに役立つGuidoの呼びかけの一つだと思います。おそらく –

    +2

    。しかし、 'int( '100 baboons')'が '1'になった場合、私にとってかなり驚くべき日になるようです。(これは、私があなたのコメントを正しく理解していれば、 )。私は、検証なしで解析する方がはるかに早くできると思いますが、それは本当に必要なものですか? (そして、その質問への答えは、私たちがさまざまな考え方などで多くのプログラミング言語を持っている理由の1つです) – mgilson

    +0

    それは私が望むものではありません。先日私がこのようなことをしていたときに例外を発生させるために私はルビを望んでいました。時には魔法がやってきます。私はこれらのような場合には明白であることを嬉しく思います。 –

    1

    ここでは、これはpythonのドキュメントに記載されていない理由の良い説明です。

    https://docs.python.org/2/library/functions.html#int

    xが数値でないか、または塩基が与えられた場合、xは基数ベースでリテラル整数を表す文字列またはUnicodeオブジェクトでなければならない場合。オプションで、リテラルの前に+または - (間に空白を入れないで)と空白で囲むことができます。ベースnのリテラルは0〜n-1の数字で構成され、a〜z(またはA〜Z)の値は10〜35です。デフォルトのベースは10です。許容値は0と2〜36です。 Base-2、-8、および-16リテラルには、オプションでコードの整数リテラルのように、0b/0B、0o/0O/0、または0x/0Xという接頭辞を付けることができます。基本0は文字列を整数リテラルとして正確に解釈することを意味し、実際の基数は2,8,10または16です。

    基本的に文字列から整数への型キャストには、 "我々は2つの部分としてフロートを考えると、我々はそれらのいずれかを捨てることができますので、このフロートの外にint型を作る 『という意味」

    +0

    厳密には、数字に '。'が含まれているかどうかだけではありません。科学的な表記法はまた、文字列のintnessを破る可能性があります。 例: 'int(" 6e7 ")'は整数ではありません(base-10)。しかし、 'int(" 6e7 "、16)' = 1767は、基数16(または任意の基数> = 15)の整数です。しかし 'int(" 6e-7 ")'は決していかなる基底でもintではありません。 – smci

    2

    私たちは何の良い、明確なアイデアを持っている』。

    それはそれほど明白ではありませんこの文字列を浮動小数点数にすると、文字列の内容に関するあらゆる種類の微妙なことが暗黙のうちに明示されます。

    短い答えは:Pythonは魅力的なものが好きで、魔法を嫌う。

    1

    逆順互換性。これは確かに可能ですが、try ...に頼っている非常に古いPythonのイディオムとの後方互換性が損なわれるので、これはひどい考えです...ラダーを除いて("許諾より許しても簡単です")を使用して、文字列の内容のタイプを判別します。このイディオムは、少なくともPython 1.5、AFAIK以降で使われています。 [1][2]

    s = "foo12.7" 
    #s = "-12.7" 
    #s = -12 
    
    try: 
        n = int(s) # or else throw an exception if non-integer... 
        print "Do integer stuff with", n 
    except ValueError: 
        try: 
         f = float(s) # or else throw an exception if non-float... 
         print "Do float stuff with", f 
        except ValueError: 
         print "Handle case for when s is neither float nor integer" 
         raise # if you want to reraise the exception 
    

    、別のマイナーなもの:ここでは、2つの引用があるそれは番号が含まれているかどうかについてだけではありません「」科学的表記、または任意の文字は、文字列のintnessを破る可能性があります。 例:int("6e7")は整数ではありません(ベース10)。ただし、int("6e7",16) = 1767は、16進数(または任意の15進数)の整数です。しかし、int("6e-7")は決してintではありません。

    ベースをベース36に拡張すると、正当な英数字の文字列(またはUnicode)は整数を表すものとして解釈できますが、デフォルトでは、通常 "dog"または " cat "は整数への参照ではありません)。

    関連する問題