【Python】isinstanceでインスタンスのクラスを判別【入門第48回】

160, 2019-09-08

目次

isinstanceの使い方

こんにちは、narupoです。

今回はPythonのisinstance関数の使い方について解説します。
isinstanceクラスのインスタンスが、何のクラスから作られたかというのを判定するのに使います。
このisinstanceは、関数やメソッドの引数をチェックしたり、バリデーションをする時によく使われます。

isinstanceについて、具体的には↓を見ていきます。

  • isinstanceで型を判定する

  • 継承したクラスのインスタンス

  • 多重継承したクラスのインスタンス

  • isinstanceで複数のクラスを判定する

  • 第2引数に渡せるオブジェクト

  • isinstanceを使った関数の引数のバリデーション

isinstanceで型を判定する

isinstanceは↓のように使います。

isinstance(オブジェクト, クラス)

isinstanceは、第1引数のオブジェクトが、第2引数のクラスまたはサブクラスのインスタンスだった時にTrue, そうでなければFalseを返します。
たとえば↓のようにです。

print(isinstance(1, int))

↑のコードの実行結果はTrueになります。
整数1intクラスのインスタンス(オブジェクト)だからですね。

逆に↓の場合はFalseになります。

print(isinstance(1, str))

整数1strクラスのインスタンスではないので↑のコードの結果はFalseになります。

継承したクラスのインスタンス

isinstanceはインスタンスのクラスをさかのぼって判定することができます。
たとえばTrueオブジェクトの判定はどうなるでしょうか。

print(isinstance(True, bool))

Trueオブジェクトはboolクラスのインスタンスなので、↑の結果はTrueになります。
では↓のコードはどうでしょうか。

print(isinstance(True, int))

↑のコードの実行結果はTrueになります。
↑はなぜTrueになるのかと言うと、boolクラスがintクラスのサブクラスだからです。

なので↓のようなコードも結果はTrueになります。

class Animal:
    pass

class Cat(Animal):
    pass

class Lion(Cat):
    pass

lion = Lion()

print(isinstance(lion, Lion))
print(isinstance(lion, Cat))
print(isinstance(lion, Animal))

↑のコードの実行結果は↓のようになります。

True
True
True

多重継承したクラスのインスタンス

isinstanceは多重継承したクラスのインスタンスも判定できます。
たとえば↓のようなコードです。

class Base1:
    pass

class Base2:
    pass

class Sub(Base1, Base2):
    pass

sub = Sub()

print(isinstance(sub, Sub))
print(isinstance(sub, Base1))
print(isinstance(sub, Base2))

↑のコードの実行結果は↓のようになります。

True
True
True

変数subSubクラスのインスタンスです。
SubクラスはBase1クラスとBase2クラスを継承しているので、↑のようなisinstanceの結果はTrueになります。

isinstanceで複数のクラスを判定する

isinstance関数の第2引数にクラスを含んだタプルを渡すこともできます。

print(isinstance(True, (bool, str)))

↑の場合、Trueオブジェクトがタプルの中のいずれかのクラスのインスタンスであれば結果はTrueになります。
よって↑の場合の結果はTrueです。

↓のようにタプルの中に生成元のクラスが含まれていなければ結果はFalseになります。

print(isinstance(True, (float, str)))

第2引数に渡せるオブジェクト

isinstance関数の第2引数に渡すことができるのは型かタプルのみです。
それ以外のオブジェクトはTypeErrorになります。

try:
    isinstance(0, 0)
except TypeError as e:
    print(e)

try:
    isinstance(0, None)
except TypeError as e:
    print(e)

try:
    isinstance(0, [int, float])
except TypeError as e:
    print(e)

↑のコードの実行結果は↓のようになります。

isinstance() arg 2 must be a type or tuple of types
isinstance() arg 2 must be a type or tuple of types
isinstance() arg 2 must be a type or tuple of types

isinstanceを使った関数の引数のバリデーション

関数の引数で型をチェックしたい時は↓のようなコードが考えられます。

def func(x):
    if not isinstance(x, int):
        raise TypeError('xがint型じゃありません')
    print(x)

func(123)
func(True)
func('猫')

↑のコードの実行結果は↓のようになります。

123
True
Traceback (most recent call last):
  File "sample.py", line 8, in <module>
    func('猫')
  File "sample.py", line 3, in func
    raise TypeError('xがint型じゃありません')
TypeError: xがint型じゃありません

おわりに

isinstanceはオブジェクトのクラスをさかのぼって判定できるので、型のバリデーションなので重宝する関数です。
関連にtypeクラスがありますが、typeクラスは型そのものを取得するので、さかのぼった判定は出来ません。
isinstanceとうまく使い分けて使うようにしましょう。

以上、次回に続きます。

また見てね

関連動画

TODO: 動画

スポンサーリンク

スポンサーリンク

スポンサーリンク

スポンサーリンク