人人都会AI编程

5.1 一切皆对象:类型对象、实例对象、函数、类的对象本质

更新时间:2026-07-12

在 Python 中,“一切皆对象”不是一句口号,而是语言底层统一的设计原则。无论是你创建的数字、字符串,还是定义的函数、类,它们都是对象。更关键的是,连类型本身也是对象,这就形成了一个自洽的对象体系。

任何变量都是对象

尝试在一个交互式环境中查看:

x = 10
print(type(x))   # <class 'int'>

def foo():
    pass
print(type(foo)) # <class 'function'>

class Bar:
    pass
print(type(Bar)) # <class 'type'>
  • 整数 10 是对象,它的类型是 int
  • 函数 foo 本身也是对象,它的类型是 function
  • Bar 同样是对象,它的类型是 type

也就是说,Python 中不存在“原始类型”的概念——在 Java 里 int 是基本类型,但在 Python 中 int 实例就是一个货真价实的对象,你可以给它添加属性(不推荐但可以做),可以检查它的 id、引用计数等所有对象共有的特征。

类型也是对象,对象必有类型

Python 对象的类型构成了一个层级关系。一切对象的终极类型源头可以追溯到两个核心元类型:typeobject

  • object 是所有类的基类,任何自定义类默认继承自它(如果没指定别的父类)。
  • type 是所有类型(包括它自己)的元类。也就是说,type 的类型还是 type

验证一下:

print(type(int))        # <class 'type'>
print(type(type))       # <class 'type'>
print(type(object))     # <class 'type'>

print(isinstance(int, object))    # True
print(isinstance(type, object))   # True

可以看到,int 的类型是 type(因为 int 是一种类型),而 type 的类型也是 type(它自己就是自己的类型)。同时,所有的类型都继承自 objecttype 也不例外。

这个关系可以用简单的记忆图来理解:

  • object ← 所有类的基类(包括 type 也是它的子类)
  • type ← 所有类型的元类(包括 object 的类型也是它)

实例对象 vs 类对象 vs 函数对象

实例、类、函数都是对象,但在内存中的结构和角色有细微差异:

  • 实例对象:由类实例化得到,其 type 指向具体的类。例如 x = 10xint 类的实例。
  • 类对象:类定义本身也是一个对象,其类型是 type(或自定义的元类)。类对象可以作为属性容器(存放类变量、方法),同时也是创建实例的“工厂”。
  • 函数对象:用 def 定义的函数是一个 function 类型的对象,支持调用 () 操作。函数对象也是一等公民:可以赋值给变量、作为参数传递给其他函数、作为返回值。
def greet(name):
    return f"Hello, {name}"

# greet 就是一个对象,我们可以操作它
f = greet          # 赋值给变量
print(f("Alice"))  # 调用
print(greet.__name__)  # 每个函数对象都有 __name__ 等属性

这个设计到底有什么用?

理解“一切皆对象”能帮你明白很多底层行为:

  1. 动态类型:因为对象本身携带了类型信息,变量只是标签,同一个标签可以随时贴上不同类型的对象。
  2. 鸭子类型:你不用检查对象的类型是否属于某个类,只要它有你需要的方法/属性就可以用。因为本质上所有操作都是在动态查找对象身上的方法,不受静态类型体系的束缚。
  3. 元编程的基础:因为类也是对象,我们可以在运行时修改类、动态创建类、使用描述符和元类来控制类的行为。这在其他静态语言中需要用到复杂的反射机制,而 Python 中就是一门对象操作的延伸。
  4. 内存管理的一致性:所有对象都继承自 object,共享相同的引用计数和垃圾回收机制,内存管理模型极其统一。

记住一句话:在 Python 里,你写的每一行代码,操作的每一个名字,都是在跟对象打交道。哪怕是简单的赋值、函数调用、类定义,背后都是一个封装好类型、状态和行为的对象。这种一致性,是 Python 动态能力和灵活性的基石,也是理解装饰器、元类、描述符等高级特性的前置心法。