Python中isinstance()和type()的区别

Python中isinstance()和type()的区别

技术背景

在Python编程中,有时候我们需要检查对象的类型,以此来决定程序的执行逻辑。type()isinstance() 是两种常用的检查对象类型的方法,但它们在功能和使用场景上有所不同。了解它们的区别,有助于我们编写出更加健壮、灵活的代码。

实现步骤

type()

type() 函数用于返回对象的类型。它只检查对象的确切类型,不考虑继承关系。示例如下:

1
2
3
4
5
6
7
8
class Vehicle:
pass

class Truck(Vehicle):
pass

print(type(Vehicle()) == Vehicle) # returns True
print(type(Truck()) == Vehicle) # returns False

isinstance()

isinstance() 函数用于检查一个对象是否是某个类或其子类的实例。它会考虑继承关系,支持子类。示例如下:

1
2
3
4
5
6
7
8
class Vehicle:
pass

class Truck(Vehicle):
pass

print(isinstance(Vehicle(), Vehicle)) # returns True
print(isinstance(Truck(), Vehicle)) # returns True

支持多类型检查

isinstance() 允许检查对象是否是多个可能类型的实例,支持多继承检查,而 type() 使用 type(obj) in (A, B, C) 虽然能检查,但不支持子类的替换。示例如下:

1
2
3
4
5
6
7
8
9
10
11
class Base1:
pass

class Base2:
pass

class Derived(Base1):
pass

obj = Derived()
print(isinstance(obj, (Base1, Base2))) # returns True

核心代码

type() 示例

1
2
3
4
5
6
7
8
9
10
11
def foo(data):
'''accepts a dict to construct something, string support in future'''
if type(data) is not dict:
# we're only going to test for dicts for now
raise ValueError('only dicts are supported for now')

from collections import OrderedDict
try:
foo(OrderedDict([('foo', 'bar'), ('fizz', 'buzz')]))
except ValueError as e:
print(e) # 'only dicts are supported for now'

isinstance() 示例

1
2
3
4
5
6
7
8
def foo(a_dict):
if not isinstance(a_dict, dict):
raise ValueError('argument must be a dict')
return a_dict

from collections import OrderedDict
result = foo(OrderedDict([('foo', 'bar'), ('fizz', 'buzz')]))
print(result) # OrderedDict([('foo', 'bar'), ('fizz', 'buzz')])

使用抽象基类

1
2
3
4
5
6
7
from collections import Mapping

def foo(a_dict):
if not isinstance(a_dict, Mapping):
raise ValueError('argument must be a dict')
return a_dict

最佳实践

多使用 isinstance()

由于 isinstance() 支持继承,可以处理子类的类型检查,所以在大多数情况下,推荐使用 isinstance() 进行类型检查。

结合抽象基类

使用 collections 模块中的抽象基类,可以让代码更加灵活和健壮。例如检查对象是否实现了 Mapping 协议时,可以使用 isinstance(obj, Mapping)

优先考虑鸭式类型

在Python中,通常优先采用“鸭式类型”(Duck Typing)的方式,避免显式地进行类型检查。尝试直接使用对象的方法,如果对象不支持相应的操作,会抛出适当的异常,再进行异常处理。示例如下:

1
2
3
4
5
6
def function_of_duck(duck):
try:
duck.quack()
duck.swim()
except AttributeError:
print("The object does not behave like a duck.")

常见问题

检查布尔值时的差异

在Python中,TrueFalseint 类型的子类。因此,isinstance(True, int)isinstance(False, int) 都返回 True,但 type(True) == inttype(False) == int 都返回 False。示例如下:

1
2
print(isinstance(True, int))  # returns True
print(type(True) == int) # returns False

相对导入和绝对导入

在编写代码时,尽量避免同时使用相对导入和绝对导入,推荐使用从项目目录添加的绝对导入,以防止类型检查时出现混淆。


Python中isinstance()和type()的区别
https://119291.xyz/posts/python-isinstance-and-type-differences/
作者
ww
发布于
2025年5月30日
许可协议