全部学科
Python全栈
python
NodeJS全栈
nodejs
小程序首页
📅 2026-05-19 10 分钟 ✍️ juanwangdev

Python type元类基础

type既是所有类型的元类,也是创建类的工具。理解元类是掌握Python面向对象的关键。

type 的双重身份

Python
# type 是内置函数:查看对象类型
print(type(1))          # <class 'int'>
print(type("hello"))    # <class 'str'>
print(type([1, 2]))     # <class 'list'>

# type 是元类:创建类
MyClass = type('MyClass', (), {})
print(MyClass)          # <class '__main__.MyClass'>
print(type(MyClass))    # <class 'type'>

# type 是自身的实例
print(type(type))       # <class 'type'>

使用 type 动态创建类

Python
# type(name, bases, dict)
# name: 类名
# bases: 基类元组
# dict: 类属性和方法字典

# 创建简单类
Simple = type('Simple', (), {'attr': 123})
print(Simple.attr)      # 123

# 创建带方法的类
def greet(self):
    return f"Hello from {self.name}"

Person = type('Person', (), {
    'name': 'Anonymous',
    'greet': greet
})

p = Person()
print(p.greet())        # Hello from Anonymous
Python
# 创建带继承的类
class Base:
    base_attr = "from base"

def extra_method(self):
    return "extra"

Derived = type('Derived', (Base,), {
    'derived_attr': "from derived",
    'extra': extra_method
})

d = Derived()
print(d.base_attr)      # from base
print(d.derived_attr)   # from derived
print(d.extra())        # extra

类创建过程

Python
# 类创建的完整流程
class MyClass(BaseClass):
    attr = 123

    def method(self):
        pass

# 等价于以下步骤:

# 1. 确定元类
metaclass = type(BaseClass)  # 默认继承基类的元类

# 2. 收集属性
namespace = {'attr': 123, 'method': method}

# 3. 调用元类的 __prepare__(创建命名空间)
namespace = metaclass.__prepare__(name, bases)

# 4. 执行类体,填充命名空间

# 5. 调用元类的 __new__(创建类对象)
cls = metaclass.__new__(metaclass, name, bases, namespace)

# 6. 调用元类的 __init__(初始化类)
metaclass.__init__(cls, name, bases, namespace)

prepare 方法

Python
class OrderedMeta(type):
    "保持属性定义顺序的元类"

    @classmethod
    def __prepare__(mcs, name, bases):
        return {}  # 返回命名空间容器

    def __new__(mcs, name, bases, namespace):
        # 查看属性顺序
        print(f"类 {name} 的属性顺序:")
        for key in namespace:
            print(f"  {key}")
        return super().__new__(mcs, name, bases, namespace)

class OrderedClass(metaclass=OrderedMeta):
    a = 1
    b = 2
    c = 3

# 输出属性顺序(Python 3.6+ 默认保持顺序)

元类继承链

Python
# 所有类的元类默认是 type
print(type(object).__name__)  # type
print(type(int).__name__)     # type
print(type(str).__name__)     # type

# 元类的继承链
class CustomMeta(type):
    pass

class CustomClass(metaclass=CustomMeta):
    pass

print(type(CustomClass).__name__)      # CustomMeta
print(type(CustomMeta).__name__)       # type
print(type(type).__name__)             # type

type 的内部结构

Python
# type 是一个类
print(type.__name__)       # 'type'
print(type.__bases__)      # (<class 'object'>,)
print(type.__mro__)        # (<class 'type'>, <class 'object'>)

# type 的特殊方法
print(type.__call__)       # 负责创建实例/类
print(type.__new__)        # 创建类对象
print(type.__init__)       # 初始化类对象
Python
# 模拟 type.__call__
def simulate_type_call(metaclass, name, bases, namespace):
    "模拟 type 创建类的过程"

    # 1. __new__ 创建类对象
    cls = metaclass.__new__(metaclass, name, bases, namespace)

    # 2. __init__ 初始化类对象
    metaclass.__init__(cls, name, bases, namespace)

    return cls

# 等价于
MyClass = type('MyClass', (), {})

type 与 object 的关系

Python
# object 是所有类的基类
print(object.__bases__)    # ()
print(type.__bases__)      # (<class 'object'>,)

# object 的类型是 type
print(type(object))        # <class 'type'>

# type 是 object 的子类
print(isinstance(type, object))  # True

# 循环关系:
# - object 是 type 的实例
# - type 是 object 的子类
# - type 是自身的实例

# 验证
print(isinstance(object, type))  # True
print(isinstance(type, type))    # True
print(issubclass(type, object))  # True

实例创建流程

Python
class MyClass:
    def __new__(cls, *args, **kwargs):
        print("MyClass.__new__ called")
        instance = super().__new__(cls)
        return instance

    def __init__(self, *args, **kwargs):
        print("MyClass.__init__ called")

# 创建实例时
obj = MyClass()

# 等价于:
# 1. type.__call__ 被调用
# 2. MyClass.__new__ 创建实例对象
# 3. MyClass.__init__ 初始化实例

元类应用场景

Python
# 场景1:自动注册子类
class RegistryMeta(type):
    registry = {}

    def __new__(mcs, name, bases, namespace):
        cls = super().__new__(mcs, name, bases, namespace)
        if name != 'Base':  # 排除基类
            mcs.registry[name] = cls
        return cls

class Base(metaclass=RegistryMeta):
    pass

class PluginA(Base):
    pass

class PluginB(Base):
    pass

print(RegistryMeta.registry)  # {'PluginA': <class PluginA>, 'PluginB': <class PluginB>}
Python
# 场景2:属性验证
class ValidatedMeta(type):
    def __new__(mcs, name, bases, namespace):
        # 检查必需属性
        if not namespace.get('_required'):
            return super().__new__(mcs, name, bases, namespace)

        for attr in namespace['_required']:
            if attr not in namespace:
                raise TypeError(f"{name} 缺少必需属性: {attr}")

        return super().__new__(mcs, name, bases, namespace)

class Strict(metaclass=ValidatedMeta):
    _required = ['name', 'version']
    name = "test"
    version = "1.0"

要点总结

  1. **type**既是函数(查看类型),也是元类(创建类)
  2. **type(name, bases, dict)**动态创建类
  3. 类创建流程:__prepare____new____init__
  4. **type**是object的子类,objecttype的实例
  5. 元类常用于自动注册、属性验证、接口强制等场景

📝 发现内容有误?点击此处直接编辑

← 上一篇 Python eval与exec安全使用
下一篇 → Python代码对象与字节码
想查看更多题目和详细解析?
小程序提供完整的题库、模拟考试和详细解析
马上就来

长按或扫描二维码,立即体验

扫码体验小程序
马上就来
使用微信扫描二维码
立即体验完整题库