Pythonで変数の型を調べる・判定する方法:type()とisinstance()の違いと使い分け

Pythonは、変数を宣言する際に型を指定する必要がない「動的型付け言語」です。そのため、プログラムの実行中に「この変数には現在どのようなデータが入っているのか」を確認したり、「数値の場合のみ計算を行う」といった型による条件分岐を行いたい場面が発生します。

Pythonには、型を扱うための主な組み込み関数として type()isinstance() の2つが用意されています。これらは似たような用途に使われますが、継承関係の扱いにおいて決定的な違いがあります。

この記事では、それぞれの基本的な使い方と、その重要な違いについて解説します。

目次

1. type() 関数:型そのものを取得する

type() 関数は、引数として渡されたオブジェクトの「型(クラス)」そのものを返します。主に、デバッグ時に変数の型をコンソールに表示して確認する際などに使用されます。

構文:

type(オブジェクト)

使用例: 数値、文字列、リスト、そして自作クラスのインスタンスの型を確認します。

# 数値 (int)
user_age = 25
print(f"user_age の型: {type(user_age)}")

# 文字列 (str)
user_name = "Tanaka"
print(f"user_name の型: {type(user_name)}")

# リスト (list)
item_list = [100, 200, 300]
print(f"item_list の型: {type(item_list)}")

# 自作クラス
class Product:
    pass

# インスタンス化
laptop = Product()
print(f"laptop の型: {type(laptop)}")

実行結果:

user_age の型: <class 'int'>
user_name の型: <class 'str'>
item_list の型: <class 'list'>
laptop の型: <class '__main__.Product'>

このように、<class '型名'> という形式で、そのオブジェクトが属するクラス情報が返されます。

2. isinstance() 関数:特定の型かどうかを判定する

isinstance() 関数は、オブジェクトが「特定の型(クラス)」であるかどうかを判定し、True または False を返します。プログラムの中で「もし文字列なら処理A、数値なら処理B」といった条件分岐を行う場合は、こちらを使用するのが一般的です。

構文:

isinstance(オブジェクト, 型)

使用例: 変数が整数型かどうか、あるいはリスト型かどうかを判定します。

# 数値の判定
score = 85
is_integer = isinstance(score, int)
print(f"score は int ですか?: {is_integer}")

# 文字列の判定
message = "Hello"
is_string = isinstance(message, str)
print(f"message は str ですか?: {is_string}")

# 異なる型での判定
# 文字列に対して「intですか?」と聞く
is_score_int = isinstance(message, int)
print(f"message は int ですか?: {is_score_int}")

実行結果:

score は int ですか?: True
message は str ですか?: True
message は int ですか?: False

また、isinstance(x, (int, float)) のように、第2引数にタプルを渡すことで「整数または浮動小数点数であれば True」といった複数の型に対する判定も可能です。

3. 最も重要な違い:継承関係の扱い

type()isinstance() の最大の違いは、クラスの継承関係を考慮するかどうかです。

  • type(): オブジェクトの厳密な型のみを見ます。親クラス(スーパークラス)は「別の型」として扱われます。
  • isinstance(): オブジェクトがそのクラスのインスタンスであるか、またはそのクラスを継承した子クラス(サブクラス)のインスタンスであるかも含めて判定します。

具体的なコード例

「乗り物(Vehicle)」クラスと、それを継承した「車(Car)」クラスを作成して挙動を比較します。

# 親クラス
class Vehicle:
    pass

# 子クラス(Vehicleを継承)
class Car(Vehicle):
    pass

# それぞれのインスタンスを作成
my_vehicle = Vehicle()
my_car = Car()

print("--- isinstance() の場合(継承を考慮) ---")
# Carのインスタンスは、Car型であり、かつVehicle型でもあるとみなされる
print(f"my_car は Car ですか?: {isinstance(my_car, Car)}")
print(f"my_car は Vehicle ですか?: {isinstance(my_car, Vehicle)}")

print("\n--- type() の場合(厳密に一致) ---")
# Carのインスタンスは、Car型とは一致するが、Vehicle型とは一致しない
print(f"my_car は Car ですか?: {type(my_car) is Car}")
print(f"my_car は Vehicle ですか?: {type(my_car) is Vehicle}")

実行結果:

--- isinstance() の場合(継承を考慮) ---
my_car は Car ですか?: True
my_car は Vehicle ですか?: True

--- type() の場合(厳密に一致) ---
my_car は Car ですか?: True
my_car は Vehicle ですか?: False

isinstance() は「車は乗り物の一種である」という継承関係を正しく認識し True を返しますが、type() は「車クラスと乗り物クラスは別物である」として False を返します。

まとめ:使い分けの指針

Pythonのプログラミングにおいては、基本的には isinstance() を使用することが推奨されます

これは、将来的に機能を拡張してサブクラスを作った際、isinstance() であれば既存のコード(親クラスを想定した処理)がそのままサブクラスにも適用できるためです(ポリモーフィズム)。

  • type(): デバッグ目的で型名を表示したい場合や、継承関係を無視して「厳密にそのクラスのインスタンスだけ」を対象にしたい特殊な場合に使用します。
  • isinstance(): 条件分岐で型チェックを行う場合の標準的な選択肢です。
よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

私が勉強したこと、実践したこと、してることを書いているブログです。
主に資産運用について書いていたのですが、
最近はプログラミングに興味があるので、今はそればっかりです。

目次