一、元类是什么?
想象一下,如果你开了一家电商公司,然后又很多分店,那么所有分店使用的标准都需要总部审核。在Python中,元类就是类似的“总部质检员”,专门负责检查每个类(分店)是否符合标准,还能自动添加统一功能。
举个栗子:所有商品类必须包含价格和SKU(商品编号)
# 普通写法(无元类)
class Product:
price = 99
# 缺少SKU并没事
# 使用元类自动检查
class ProductMeta(type):
def __new__(cls, name, bases, attrs):
if "Product" in name:
if 'price' not in attrs or 'sku' not in attrs:
raise TypeError("商品类必须包含price和sku!") # 自动报错
return super().__new__(cls, name, bases, attrs)
class Product(metaclass=ProductMeta):
price = 99 # 故意不写sku
# 运行时报错:TypeError: 商品类必须包含price和sku!
二、元类能做什么?
场景1:自动添加统一功能
比如给所有电商类自动添加日志标签,无需手动写:
class LogMeta(type):
def __new__(cls, name, bases, attrs):
attrs['log_tag'] = f"{name}类日志" # 自动添加属性
return super().__new__(cls, name, bases, attrs)
class Order(metaclass=LogMeta):
pass
print(Order.log_tag) # 输出:Order类日志
场景2:检查类属性
强制要求订单类必须有状态更新方法:
class OrderMeta(type):
def __new__(cls, name, bases, attrs):
if "Order" in name and 'update_status' not in attrs:
raise TypeError("订单类必须实现update_status方法!")
return super().__new__(cls, name, bases, attrs)
class Order(metaclass=OrderMeta):
# 如果不写update_status方法会报错
def update_status(self,status):
print(f"状态更新为:{status}")
三、元类底层原理
记住两个关键点:
- 类也是对象:所有类都是通过 type() 创建的
- 元类继承自type:通过改写 new 方法控制类的生成
# 手动用type创建类(等效于class语句)
MyClass = type('MyClass', (), {'x': 10})
# 自定义元类
class MyMeta(type):
def __new__(cls, name, bases, attrs):
print(f"正在创建类:{name}")
return super().__new__(cls, name, bases, attrs)
class Demo(metaclass=MyMeta): # 创建类 Demo
pass
四、常见问题
问题1:元类和继承的区别?
继承:修改实例的行为(如添加方法)
元类:修改类本身的创建规则(如强制属性检查)
问题2:什么时候用元类?
当需要批量控制多个类的结构时使用,比如:
电商平台统一校验商品信息
自动生成数据库表的ORM框架
总结:元类三步走
理解需求:需要统一修改多个类的结构吗?
继承type:编写元类时一定继承 type
改写__new__:在创建类时添加你的逻辑