概要(isinstance は「型やサブクラスまで含めた安全な型チェック」)
isinstance は、渡した値が指定した型(クラス)か、またはそのサブクラスであるかを真偽値で返す組み込み関数です。Python は継承や抽象型(インターフェース)を多用します。単純な一致判定よりも「その型として扱ってよいか」を判断する場面で、isinstance が正解になります。
print(isinstance(10, int)) # True
print(isinstance(True, int)) # True(bool は int のサブクラス)
print(isinstance([1, 2], (list, tuple))) # True(複数型を許容)
Python基本構文と動作(ここが重要)
2引数の基本形と複数型の許容
isinstance(obj, classinfo) の形で使います。classinfo には単一の型または「型のタプル」を渡せます。タプルを使うと、複数の型をまとめて許容できます。
print(isinstance("hello", str)) # True
print(isinstance(3.14, (int, float))) # True
print(isinstance({"a": 1}, (list, dict))) # True(dict を許容)
Python継承関係を考慮する(親クラスでも True)
サブクラスのインスタンスは、親クラスに対しても True になります。抽象基底クラス(ABC)や“インターフェース的な”型に対してのチェックが自然に書けます。
class Animal: ...
class Dog(Animal): ...
d = Dog()
print(isinstance(d, Dog)) # True
print(isinstance(d, Animal)) # True(親クラス)
Pythontype との違い(厳密一致か、実務的な「扱えるか」か)を深掘り
type は“完全一致”、isinstance は“扱える範囲”
type(x) is T は「実体が T そのものか」を見る厳密判定。isinstance(x, T) は「T として扱ってよいか」を見る柔軟判定です。ライブラリ間でクラスが拡張される現場では、原則 isinstance を選びます。
class A: ...
class B(A): ...
b = B()
print(type(b) is A) # False
print(isinstance(b, A)) # True
Python代表的な落とし穴(bool は int のサブクラス)
True/False は int を継承しています。数値のみ受けたいが「真偽値を除外したい」なら、isinstance で数値を許容したあとに bool を明示的に弾く、または最初に type(x) is bool を除外します。
def square(x):
if type(x) is bool: # 先に厳密除外
raise TypeError("bool は数値扱いしません")
if isinstance(x, (int, float)):
return x * x
raise TypeError("数値のみ受け付けます")
Python抽象基底クラス(ABC)で「振る舞いの型」をチェック
コレクション系の ABC を使うと意図が伝わる
「シーケンス(順番に並んだ要素)なら OK」「マッピング(キー→値)なら OK」など、構造や振る舞いで受けたいときは collections.abc の型を使います。派生クラスも自然に拾えます。
from collections.abc import Sequence, Mapping
def head(xs):
if not isinstance(xs, Sequence):
raise TypeError("シーケンスを渡してください")
return xs[0] if xs else None
def total(m):
if not isinstance(m, Mapping):
raise TypeError("マッピング(dict 等)を渡してください")
return sum(m.values())
Python文字列は「シーケンスでもある」ことに注意
str は Sequence の一種です。文字列を“要素集合”として扱いたくない場合は、先に isinstance(x, str) を除外してから Sequence を判定します。
from collections.abc import Sequence
def avg(xs):
if isinstance(xs, str):
raise TypeError("文字列は対象外です")
if not isinstance(xs, Sequence):
raise TypeError("数値のシーケンスを渡してください")
return sum(xs) / len(xs)
Python実務での使いどころ(入力検証・分岐・フォールバック)
入力検証で「受け入れる範囲」を明示する
ユーザー入力や外部データは型が揺れます。最初に isinstance で受け入れ可能範囲を絞ると、後続のロジックが安定します。
def parse_int(x):
if isinstance(x, int):
return x
if isinstance(x, str) and x.isdigit():
return int(x)
raise TypeError("整数または数字文字列を渡してください")
Python型ごとの分岐を読みやすく整理する
複数型を受ける関数は、型判定を上から順に短く書いて早期 return。可読性が上がり、バグが減ります。
def to_list(x):
if isinstance(x, list):
return x
if isinstance(x, tuple):
return list(x)
if isinstance(x, str):
return [x]
raise TypeError("list/tuple/str のみ対応です")
Pythonロギングやデバッグに型情報を添える
isinstance と組み合わせて「どの分岐に入ったか」を明示しておくと、障害調査の初期対応が速くなります。
def debug_route(x):
if isinstance(x, dict):
print("route=dict")
elif isinstance(x, (list, tuple)):
print("route=sequence")
else:
print("route=other")
Python応用と設計の勘所(duck typingとの線引き・型ヒントとの併用)
“duck typing”に寄せるか、isinstanceで守るか
Python は「そのメソッドが使えれば良い」という考え(duck typing)も強力です。外部入力の入口や公開 API では isinstance で防御的に。内部のホットパスでは try/except でメソッドを直接呼ぶ方が軽量な場合もあります。入口は厳しく、中は軽く、が基本のバランスです。
def safe_len(x):
# 入口なら isinstance(Sequence) の検証でも良い
try:
return len(x)
except TypeError:
raise TypeError("長さを持つオブジェクトを渡してください")
Python型ヒントと補完のための設計
isinstance によるガードは、型ヒント(typing)と相性が良いです。入口で型を絞れば、IDE の補完も安定し、静的解析ツールの誤検知が減ります。
from typing import Iterable
def mean(xs: Iterable[float]) -> float:
# 実際の受け入れは isinstance(xs, Iterable) で守る選択肢も
total = 0.0
count = 0
for x in xs:
total += x
count += 1
return total / count if count else 0.0
Python例題で身につける(定番から一歩先まで)
例題1:数値だけを受ける(bool 除外)
def area_of_square(x):
if type(x) is bool:
raise TypeError("True/False は数値として扱いません")
if not isinstance(x, (int, float)):
raise TypeError("数値を渡してください")
return x * x
print(area_of_square(3.5)) # 12.25
Python例題2:複数型を許容して正規化
def as_dict(x):
if isinstance(x, dict):
return x
if isinstance(x, (list, tuple)):
# [("k","v"), ...] を dict に
return dict(x)
raise TypeError("dict か (key, value) の列を渡してください")
print(as_dict([("a", 1), ("b", 2)])) # {'a': 1, 'b': 2}
Python例題3:ABC を使ったインターフェース受け
from collections.abc import Sequence
def tail(xs):
if not isinstance(xs, Sequence):
raise TypeError("シーケンスを渡してください")
return xs[-1] if xs else None
print(tail((1, 2, 3))) # 3
Python例題4:クラス階層での柔軟な受付
class Shape: ...
class Circle(Shape): ...
class Square(Shape): ...
def draw(s):
if not isinstance(s, Shape):
raise TypeError("Shape 系のオブジェクトを渡してください")
return f"drawing {type(s).__name__}"
print(draw(Circle()))
print(draw(Square()))
Pythonまとめ
isinstance は「この値をその型として扱ってよいか」を継承関係まで含めて判定できる、Python で最も実務的な型チェック手段です。type は厳密一致、isinstance は柔軟判定。bool が int のサブクラスという落とし穴、文字列がシーケンスである点、ABC による振る舞いチェック——これらを理解すると、入力検証・分岐・ロギングが安定し、初心者のコードは一段読みやすく堅牢になります。入口は厳しく、中は軽く。型を味方にして、意図が伝わる関数を書いていきましょう。
