isinstance() 是什么?
isinstance() 是一个 Python 内置函数,用于检查一个对象是否是某个类(或其子类)的实例,或者是否是某个元组中列出的多个类中的任意一个类的实例。

它能回答这个问题:“这个对象 obj 是不是 classinfo 这种类型?”
语法
isinstance(object, classinfo)
参数:
object: 要检查的对象,这可以是任何 Python 对象。classinfo: 可以是:- 一个类(如
int,str,list, 或者你自定义的类)。 - 一个由类组成的元组(如
(int, str))。
- 一个类(如
返回值:
object是classinfo指定的类或其子类的实例,则返回True。- 否则,返回
False。
基本用法示例
示例 1:检查基本数据类型
这是最常见的用法,用于检查一个变量是否是某种内置类型。

# 检查整数 num = 10 print(isinstance(num, int)) # 输出: True # 检查字符串 name = "Alice" print(isinstance(name, str)) # 输出: True # 检查布尔值 (注意: bool 是 int 的子类) flag = True print(isinstance(flag, bool)) # 输出: True print(isinstance(flag, int)) # 输出: True (因为 bool 继承自 int)
示例 2:检查多个类型(使用元组)
如果你想检查一个对象是否是多种类型之一,可以将这些类型放在一个元组中作为第二个参数。
data = 123 # 检查 data 是否是 int 或 str 类型 print(isinstance(data, (int, str))) # 输出: True (因为 data 是 int) data = "hello" print(isinstance(data, (int, str))) # 输出: True (因为 data 是 str) data = [1, 2, 3] print(isinstance(data, (int, str))) # 输出: False (data 既不是 int 也不是 str)
示例 3:检查自定义类的实例
isinstance() 在面向对象编程中非常有用,可以检查一个对象是否是你自己创建的类的实例。
class Animal:
pass
class Dog(Animal): # Dog 继承自 Animal
pass
# 创建实例
my_dog = Dog()
generic_animal = Animal()
# 检查 my_dog
print(isinstance(my_dog, Dog)) # 输出: True
print(isinstance(my_dog, Animal)) # 输出: True (因为 Dog 是 Animal 的子类,my_dog 也是 Animal 的实例)
print(isinstance(my_dog, object)) # 输出: True (所有类都继承自 object)
# 检查 generic_animal
print(isinstance(generic_animal, Dog)) # 输出: False
print(isinstance(generic_animal, Animal)) # 输出: True
这个例子清晰地展示了 isinstance() 的核心特性:它会考虑继承关系。A 是 B 的子类,A 的实例也必然是 B 的实例。
isinstance() vs. type()
初学者常常会混淆 isinstance() 和 type(),它们都与类型检查有关,但行为有关键区别。

type() 函数返回一个对象的精确类型,而不会考虑继承关系。
让我们用上面的 Animal 和 Dog 例子来对比:
my_dog = Dog() # 使用 type() 检查 print(type(my_dog) is Dog) # 输出: True print(type(my_dog) is Animal) # 输出: False (type() 返回的是精确类型 Dog,不是 Animal) # 使用 isinstance() 检查 print(isinstance(my_dog, Dog)) # 输出: True print(isinstance(my_dog, Animal)) # 输出: True (isinstance() 考虑了继承)
总结区别:
| 特性 | isinstance(obj, class) |
type(obj) is class |
|---|---|---|
| 检查范围 | 检查对象是否是指定类或其父类的实例。 | 检查对象的精确类型是否完全匹配指定类。 |
| 继承关系 | 考虑继承,子类实例也是父类实例。 | 不考虑继承,只检查类型本身。 |
| 推荐场景 | 推荐使用,在绝大多数情况下,尤其是在面向对象编程中,你想知道一个对象是否具有某种“行为”或“属性”(由父类定义),而不是它的具体“出身”。 | 在你需要严格区分类型,确保对象不是子类实例时使用,某些底层实现可能要求类型必须完全匹配。 |
一个生动的比喻:
isinstance(my_dog, Animal)就像问:“my_dog是一种动物吗?” 答案是肯定的,因为狗是动物。type(my_dog) is Animal就像问:“my_dog的物种精确是‘动物’吗?” 答案是否定的,它的物种是“狗”。
高级用法与注意事项
示例 4:与 numbers 模块结合使用
Python 的 numbers 模块定义了数字类型的抽象基类,非常适合进行泛化的数字类型检查。
import numbers # 整数 print(isinstance(10, numbers.Number)) # True print(isinstance(10, numbers.Integral)) # True # 浮点数 print(isinstance(3.14, numbers.Number)) # True print(isinstance(3.14, numbers.Real)) # True print(isinstance(3.14, numbers.Integral)) # False # 复数 print(isinstance(1+2j, numbers.Number)) # True print(isinstance(1+2j, numbers.Complex)) # True
这在编写需要处理多种数字类型的通用函数时非常有用。
示例 5:与 collections.abc 模块结合使用
同样,collections.abc 模块定义了容器类型的抽象基类,可以用来检查对象是否实现了某种接口(协议)。
from collections.abc import Iterable, Sized
my_list = [1, 2, 3]
my_string = "hello"
my_dict = {'a': 1}
# 检查是否可迭代
print(isinstance(my_list, Iterable)) # True
print(isinstance(my_string, Iterable)) # True
print(isinstance(my_dict, Iterable)) # True
print(isinstance(123, Iterable)) # False
# 检查是否具有大小
print(isinstance(my_list, Sized)) # True
print(isinstance(my_string, Sized)) # True
print(isinstance(my_dict, Sized)) # True
print(isinstance(123, Sized)) # False
注意事项 1:不要用 isinstance() 检查 None
None 的类型是 NoneType,虽然 isinstance(None, NoneType) 会返回 True,但这通常不是推荐的做法,更 Pythonic 的方式是直接使用 is 运算符。
# 不推荐
print(isinstance(None, type(None))) # 输出: True
# 推荐 (更清晰、更高效)
if my_variable is None:
print("my_variable is None")
注意事项 2:不要用 isinstance() 检查布尔值与 int
由于 bool 是 int 的子类 (True 是 1,False 是 0),isinstance(True, int) 会返回 True,如果你只想检查布尔值,应该使用 type()。
# 这可能会带来意想不到的结果
def process_value(value):
if isinstance(value, int):
print("这是一个整数")
else:
print("这不是一个整数")
process_value(10) # 输出: 这是一个整数
process_value(True) # 输出: 这是一个整数 (可能不是你想要的)
process_value(False) # 输出: 这是一个整数 (可能不是你想要的)
# 如果你只想处理真正的整数和布尔值分开
def process_value_correctly(value):
if type(value) is bool:
print("这是一个布尔值")
elif isinstance(value, int):
print("这是一个整数")
else:
print("这不是整数或布尔值")
process_value_correctly(10) # 输出: 这是一个整数
process_value_correctly(True) # 输出: 这是一个布尔值
| 函数 | 语法 | 核心思想 | 推荐场景 |
|---|---|---|---|
isinstance() |
isinstance(obj, classinfo) |
“是不是...的一种?” (考虑继承) | 首选,用于泛型编程、多态、以及当你关心对象是否具备某种“能力”或“类型”时。 |
type() |
type(obj) is class |
“是不是...这个精确的东西?” (不考虑继承) | 在需要严格类型匹配,排除子类实例的少数情况下使用。 |
核心要点:
isinstance()是进行类型检查的首选函数,因为它能正确处理继承关系,这更符合面向对象的思想。- 它可以检查单个类型,也可以通过元组检查多个类型。
- 它与
type()的关键区别在于是否考虑继承。 - 在编写健壮、可扩展的 Python 代码时,
isinstance()是一个非常强大的工具,尤其是在处理鸭子类型和抽象基类时。
