読者です 読者をやめる 読者になる 読者になる

おぎろぐはてブロ

なんだかんだエンジニアになって10年以上

Pythonで整数であることをチェックする

引数が整数であることを確認するのに、こんなコードをよく書いてるんだけど

if type(arg) not in (int, long):
    raise InvalidArgumentError

ちょっと冗長じゃないかな。先日は (int, tuple) とか書いてて危ない思いをしたりも。。

どうにかならんものかとつぶやくと、

if not isinstance(arg, (int, long)):

って教えてもらった。isinstanceでタプル渡せるの知らなかった。(2.2 or later)

なんだが、単語数は減ったけど文字数が減ってない。

あと、bookはintのサブクラスなため、isinstance([bool instance], int) は True となるけど、素直に文字列変換すると (True|False) の文字列になる点が要注意。

>>> arg = True
>>> print type(arg), arg
<type 'bool'> True
>>> type(arg) not in (int, long)
True
>>> not isinstance(arg, (int, long))
False

Python 2系での整数の扱い

int (整数), long (長整数) の違いは、もちろんサイズ。

C言語っぽいが、Pythonのintは「C言語の long 型を使って実装されており、少なくとも 32 ビットの精度があります 」で、long (長整数型)は「精度の制限がありません」。

長整数のレンジの数を扱うようなことは普通のお仕事ではあんまりないと思うのだけど、intで表現できる値でもlongに入っていることはあるのが面倒ですね。longを受け取るようにすると今度は巨大な整数がやってくる可能性がでてくるわけで。。

>>> type(1)
<type 'int'>
>>> type(1L)
<type 'long'>

整数についてはクラスツリーはこうなる

numbers.Number --- Integral -+- int --- bool
                             +- long

Python 3系での扱い

Python 3系では、longが無くなり、intに統一されている。 すっきり。

numbers.Number --- Integral --- int --- bool

なので、こう書ける

if type(arg) is not int:
    raise InvalidArgumentError