object 管继承(所有类的父类),type 管制造(所有类的元类);实例链与继承链两套独立体系交织出自指闭环,元类就是「实例为类的类」。

object 与 type 的本质

object:继承树的根类

  • 所有类的默认父类,class A: 等价于 class A(object):(详见Python 关键字 object)
  • 定义所有对象通用的基础方法:__repr__、__eq__、__hash__、__getattribute__ 等
  • 继承链最顶端,object.__bases__ = (),没有父类
  • 属于普通类:实例是普通对象,不能用来制造新的类

type:默认元类

  • 制造类的类(元类),所有普通类本质上都是 type 的实例
  • class 语法底层:Python 收集类体代码构建命名空间,最终调用 type(name, bases, namespace) 创建类对象
  • 两种用法:
    • 单参数 type(obj):返回对象的类型(等价于 obj.__class__)
    • 三参数 type(name, bases, namespace):动态创建新类

两条独立的关系链

实例链(制造关系):__class__ / type()

回答「这个对象是谁制造出来的实例」:

普通实例 → 普通类(object/int/自定义类) → type → type(自指)
print(type(object()))  # <class 'object'>  普通实例的类是 object
print(type(object))    # <class 'type'>    object 类本身是 type 的实例
print(type(type))      # <class 'type'>    type 自身是 type 的实例(自实例化)

继承链(is-a 关系):__bases__ / issubclass()

回答「这个类继承自谁」,规则见继承与 MRO:

自定义类 → ... → object(顶端)
type → object
print(object.__bases__)          # ()  object 无父类,是继承根
print(type.__bases__)            # (object,)  type 继承自 object
print(issubclass(type, object))  # True

自指闭环

三命题同时成立:

  1. object 是 type 的实例:object 这个类对象,由 type 实例化创建
  2. type 继承自 object:type 作为一个类,遵循 object 定义的接口规范
  3. type 是自身的实例:元类自身也是类,由自己实例化

为何不死循环?CPython 启动时先为 object 和 type 分配内存空间,再互相绑定引用指针——不是线性的「先有鸡还是先有蛋」,因此不存在逻辑死循环。

自定义元类

元类是实例为类的类,判断标准:继承自 type。Python 内置原生元类只有 type 一个,继承 type 即可修改类的创建逻辑:

class MyMeta(type):
    def __new__(cls, name, bases, namespace):
        print(f"创建类:{name}")
        # 调用父类(type)的 __new__ 完成实际创建
        return super().__new__(cls, name, bases, namespace)
 
class MyClass(metaclass=MyMeta):  # 指定元类创建类
    pass
 
print(type(MyClass))  # <class '__main__.MyMeta'>

常见误区

  • ❌「object 是元类」:object 是普通根类,实例是普通对象,无法创建类
  • ❌「元类只有 type」:所有继承 type 的类都是元类,type 只是所有元类的根

type() vs isinstance()

  • type(obj):严格返回对象的 __class__,只看直接类型,不考虑继承
  • isinstance(obj, cls):判断对象是否是 cls 的实例,会沿继承链向上查找
print(isinstance(object, object))  # True:type(object) 是 type,而 type 是 object 的子类
print(type(object) is object)      # False:type(object) 是 type,不是 object

OOP 语言对比

语言一切皆对象根父类类是否为对象元类/自指闭环
Python是object是,类是 type 的实例是,type 自实例化,type 继承 object 形成闭环
Smalltalk是Object是,类是 Class 的实例是,Class.class = Class
Ruby是Object是,类是 Class 的实例是,Class.class = Class
Java否(基本类型不是)Object否,仅存在 Class 元数据对象无原生元类闭环
C#否(值类型不是)object否,仅存在 Type 元数据无
C++否无统一根类否无
JavaScript是(原型体系)Object.prototype否,class 是原型语法糖原型自环,非元类模型

类创建之后的属性存储与访问机制,见类属性与实例属性与属性访问与查找。