[解決!Python]type関数やisinstance関数でオブジェクトの型を確認するには解決!Python

何らかのオブジェクトの型を知りたいときには、type関数とisinstance関数が使える。それらの使い方の基本を紹介する。

» 2023年09月05日 05時00分 公開
[かわさきしんじDeep Insider編集部]

この記事は会員限定です。会員登録(無料)すると全てご覧いただけます。

「解決!Python」のインデックス

連載目次

# type関数
a = 1
t = type(a)
print(t)  # <class 'int'>

tt = type(t)  # type関数の戻り値の型
print(tt)  # <class 'type'>

tt = type(int)  # int型(intクラス)の型
print(tt)  # <class 'type'>

# オブジェクトの型で振る舞いを変えるには
if type(a) == int:
    print(f'{a}の型はintです')
elif type(a) == float:
    print(f'{a}の型はfloatです')

n = 1.2
t = type(n)
if t == int or t == float or t == complex:
    print(f'{n} is number: {t}'# 1.2 is number: <class 'float'>

if t in (int, float, complex):
    print(f'{n} is number: {t}'# 1.2 is number: <class 'float'>

# isinstance関数
result = isinstance(1, int)
print(result)  # True

result = isinstance(1.2, (int, float, complex))
print(result)  # True

class A:
    pass

class B(A):
    pass

b = B()
result = isinstance(b, A)
print(result)  # True

class C:
    pass

c = C()
result = isinstance(c, A)
print(result)  # False

n = 1.2

if isinstance(n, (int, float, complex)):
    print(f'{n} is number: {type(n)}'# 1.2 is number: <class 'float'>

if isinstance(n, int | float | complex):
    print(f'{n} is number: {type(n)}'# 1.2 is number: <class 'float'>

import numbers

result = isinstance(1, numbers.Number)
print(result)

result = isinstance(1.2, numbers.Number)
print(result)

result = isinstance(1.2 + 1.0j, numbers.Number)
print(result)

if isinstance(n, numbers.Number):
    print(f'{n} is number: {type(n)}'# 1.2 is number: <class 'float'>


type関数とisinstance関数によるオブジェクトの型チェック

 Pythonであるオブジェクトの型を知るには以下の2つの方法がある。

  • type関数:「type(obj)」のように、型を知りたいオブジェクトを渡すと、そのオブジェクトの型が返される
  • isinstance関数:「isinstance(obj, type_obj)」のようにあるオブジェクト(obj)と、そのオブジェクトが属しているかどうかを知りたい型(type_obj)を指定すると、objがtype_objのインスタンスが、その派生クラスのインスタンスである場合にはTrueが、そうでなければFalseが返される

 なお、「type関数のドキュメント」には「オブジェクトの型の判定には、 isinstance() 組み込み関数を使うことが推奨されます。これはサブクラスを考慮するからです」とあることには留意しよう(とはいうものの、ちょっと知りたいというときには筆者もtype関数をよく使っている)。

type関数

 type関数に何かのオブジェクトを渡すと、そのオブジェクトの型が返される。以下に例を示す。

a = 1
t = type(a)
print(t)  # <class 'int'>


 この例では整数値の1を渡しているので、その型として「<class 'int'>」が返されている。この戻り値はtype型のオブジェクトになっている。また、通常のintクラスオブジェクトもまたtype型のオブジェクトである。

tt = type(t)  # type関数の戻り値の型
print(tt)  # <class 'type'>

tt = type(int)  # int型(intクラス)の型
print(tt)  # <class 'type'>


 つまり、type関数の戻り値とintやfloat、その他の組み込み型やユーザー定義のクラスなどはtype型のオブジェクトであり、これらを比較できる。このことを使って、あるオブジェクトが特定の型であった場合に、何らかの処理を実行するといったことが可能だ。

if type(a) == int:
    print(f'{a}の型はintです')
elif type(a) == float:
    print(f'{a}の型はfloatです')


 あるオブジェクトが特定の幾つかの型のいずれかであるかどうかを知りたいのであれば、or演算子を使って次のように書ける。

n = 1.2
t = type(n)
if t == int or t == float or t == complex:
    print(f'{n} is number: {t}'# 1.2 is number: <class 'float'>


 これは煩雑なので、in演算子を使って次のようにも書ける。

if t in (int, float, complex):
    print(f'{n} is number: {t}'# 1.2 is number: <class 'float'>


 この書き方も必要な情報は全てプログラマーの側が列挙しなければならないという点では上の例とそれほど変わらない。

 これに対して、isinstance関数はクラス階層を考慮してくれるという点で便利だ。

isinstance関数

 ただ、その前にisinstance関数の基本的な使い方を紹介しておこう。既に述べた通り、isinstance関数にはオブジェクトと、それが属しているかどうかを知りたい型を渡す。すると、そのオブジェクトがその型のインスタンスか、その型の派生クラスのインスタンスであればTrueが、そうでなければFalseが返される。

result = isinstance(1, int)
print(result)  # True


 これは整数値の1がint型かどうかを調べるコードで、その結果はもちろんTrueになる。調べたい型が複数あるのであれば、それらをタプルとして渡してもよい。

result = isinstance(1.2, (int, float, complex))
print(result)  # True


 この例では浮動小数点数値の1.2がintかfloatかcomplexのいずれかの型のインスタンスかどうかを調べている。これもまた結果はTrueになる。

 以下はユーザー定義クラスとそのインスタンスの比較の例だ。

class A:
    pass

class B(A):
    pass

b = B()
result = isinstance(b, A)
print(result)  # True


 この場合、クラスBはクラスAを継承しているので、クラスBのインスタンスもクラスAのインスタンスとして扱われている。

 一方、継承階層に含まれないクラスがどうなるかを示したのが以下だ。

class C:
    pass

c = C()
result = isinstance(c, A)
print(result)  # False


 この場合はもちろん、クラスCのインスタンスはクラスAのインスタンスではないとなる。

 isinstance関数を使って、先ほどのtype関数の例として示した浮動小数点数値の1.2がint、float、complexのいずれかであるかを調べるには次のような方法がある。

n = 1.2

if isinstance(n, (int, float, complex)):
    print(f'{n} is number: {type(n)}'# 1.2 is number: <class 'float'>


 これは全ての型を列挙するという意味ではtype関数を使うのそれほど違いはない。なお、Python 3.10以降ではUnion Typeを使って以下のようにも記述できる。

if isinstance(n, int | float | complex):
    print(f'{n} is number: {type(n)}'# 1.2 is number: <class 'float'>


 ところで、Pythonには抽象基底クラス(Abstract Base Type、ABC)という機構がある。そして、数値関連の型(int、floatなど)はnumbersモジュールが提供するnumbers.Numberクラスの(仮想的な)派生クラスとなっている。以下はこのことを確認するものだ。

import numbers

result = isinstance(1, numbers.Number)
print(result)

result = isinstance(1.2, numbers.Number)
print(result)

result = isinstance(1.2 + 1.0j, numbers.Number)
print(result)


 数値は全てnumbers.Numberクラスの派生クラスであるので、上記のコードは次のようにも書ける。

if isinstance(n, numbers.Number):
    print(f'{n} is number: {type(n)}'# 1.2 is number: <class 'float'>


 このようにクラスの継承階層まで意識して、オブジェクトの型をチェックしたいときにはisinstance関数を使うのがよいだろう。

「解決!Python」のインデックス

解決!Python

Copyright© Digital Advantage Corp. All Rights Reserved.

スポンサーからのお知らせPR

注目のテーマ

Microsoft & Windows最前線2025
AI for エンジニアリング
ローコード/ノーコード セントラル by @IT - ITエンジニアがビジネスの中心で活躍する組織へ
Cloud Native Central by @IT - スケーラブルな能力を組織に
システム開発ノウハウ 【発注ナビ】PR
あなたにおすすめの記事PR

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。