isinstance() 是默认选择,因它检查对象是否为某类或其任意子类实例,符合Python继承模型和鸭子类型习惯;支持元组参数、自定义子类及抽象基类,而type()仅严格匹配确切类型。

用 isinstance() 判断类型基本不会出错,用 type() 容易漏掉子类、破坏多态,除非你明确需要精确类型匹配。
isinstance() 为什么是默认选择
它检查对象是否为某类或其任意子类的实例,符合 Python 的继承模型和鸭子类型习惯。比如 bool 是 int 的子类,isinstance(True, int) 返回 True,而很多逻辑(如数值计算)确实需要把 bool 当作 int 处理。
- 支持元组参数:
isinstance(obj, (str, bytes))可一次性判断多种类型 - 兼容自定义子类:只要
MyList继承list,isinstance(my_list, list)就为True - 与标准库抽象基类协同良好:如
isinstance(d, collections.abc.Mapping)能识别dict、defaultdict、ChainMap等
type() 适合什么场景
type() 返回的是对象的**确切类型对象**,比较时必须完全一致,不向上追溯父类。它只在你需要排除所有子类、做严格类型隔离时才适用。
- 典型用途:序列化/反序列化中防止恶意子类注入;调试时打印类型名(配合
__name__) - 写法必须用
is,不是==:type(obj) is dict—— 因为类型对象是单例 -
type(obj) is list对collections.UserList实例返回False,哪怕行为几乎一样
常见错误:用 type() == str 或忽略 ABC
直接写 type(obj) == str 不仅低效,还可能因第三方字符串类(如 pathlib.Path 子类)失效;更严重的是,用 type(obj) is list 来判断“可迭代容器”,会漏掉 tuple、deque、甚至实现了 __iter__ 的自定义类。
立即学习“Python免费学习笔记(深入)”;
- 错误示例:
if type(data) is list: process_list(data)→deque或array.array进不来 - 正确替代:
if isinstance(data, collections.abc.Sequence)(语义更准)或if hasattr(data, '__iter__')(鸭子类型) - 性能提示:
isinstance()在 CPython 中做了优化,比type()+is略慢但可忽略;真正慢的是反复调用+反射
最易被忽略的一点:类型判断从来不是目的,而是为了后续操作安全。如果后续要调 obj.append(),与其先 isinstance(obj, list),不如直接 hasattr(obj, 'append') 或捕获 AttributeError —— 更 Pythonic,也更贴近真实需求。


















