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"
要点总结
- **
type**既是函数(查看类型),也是元类(创建类) - **
type(name, bases, dict)**动态创建类 - 类创建流程:
__prepare__→__new__→__init__ - **
type**是object的子类,object是type的实例 - 元类常用于自动注册、属性验证、接口强制等场景
📝 发现内容有误?点击此处直接编辑