在 Python 开发中,根据 JSON 数据动态生成类并让生成的类支持序列化,能够满足配置驱动类结构、动态适配数据模型的场景需求,避免手动编写大量重复的类定义代码。

动态生成 Python 类的核心方法
Python 中动态创建类最常用的方式是使用内置的 type 函数,该函数可以接收三个参数:类名、父类元组、属性字典,最终返回一个新的类对象。我们可以解析 JSON 中的属性定义,将其转化为属性字典传入 type 函数,完成类的动态构建。
基础动态类生成示例
以下代码演示了从简单的 JSON 结构解析属性,动态生成类的基础过程:
import json
# 定义用于生成类的 JSON 配置,包含类名和属性列表
class_config = {
"class_name": "User",
"attributes": ["name", "age", "email"]
}
def create_class_from_json(config):
class_name = config["class_name"]
# 初始化属性字典,包含初始化方法
attrs = {
"__init__": lambda self, **kwargs: setattr(self, "__dict__", kwargs)
}
# 遍历 JSON 中的属性列表,为类添加默认属性
for attr in config["attributes"]:
attrs[attr] = None
# 使用 type 动态创建类
return type(class_name, (object,), attrs)
# 生成 User 类
User = create_class_from_json(class_config)
user = User(name="张三", age=25, email="test@ipipp.com")
print(user.name) # 输出:张三
print(user.age) # 输出:25
为动态生成的类添加可序列化能力
可序列化要求类的实例能够转换为 JSON 格式,通常可以通过实现 to_dict 方法,或者自定义 JSON 编码器来实现。我们可以在动态生成类的时候,为类添加序列化相关的方法,让生成的类天然支持序列化。
实现序列化方法的动态类
下面的代码扩展了动态类生成逻辑,为生成的类添加 to_dict 方法和支持 JSON 序列化的 __repr__ 方法:
import json
class_config = {
"class_name": "Product",
"attributes": ["product_id", "product_name", "price"]
}
def create_serializable_class_from_json(config):
class_name = config["class_name"]
attrs = {}
# 初始化方法,接收关键字参数并赋值给实例属性
def init(self, **kwargs):
for key, value in kwargs.items():
setattr(self, key, value)
attrs["__init__"] = init
# 添加 to_dict 方法,用于将实例转换为字典
def to_dict(self):
return {k: v for k, v in self.__dict__.items() if not k.startswith("_")}
attrs["to_dict"] = to_dict
# 添加 __repr__ 方法,方便打印查看实例内容
def repr(self):
return f"<{class_name} {self.to_dict()}>"
attrs["__repr__"] = repr
# 动态创建类
return type(class_name, (object,), attrs)
# 生成可序列化的 Product 类
Product = create_serializable_class_from_json(class_config)
product = Product(product_id=1001, product_name="笔记本电脑", price=4999.99)
# 调用 to_dict 方法转为字典
product_dict = product.to_dict()
print(product_dict) # 输出:{"product_id": 1001, "product_name": "笔记本电脑", "price": 4999.99}
# 转为 JSON 字符串
product_json = json.dumps(product_dict, ensure_ascii=False)
print(product_json) # 输出:{"product_id": 1001, "product_name": "笔记本电脑", "price": 4999.99}
支持嵌套结构的动态类生成
实际场景中 JSON 可能包含嵌套结构,比如某个属性是另一个类的实例,我们可以在生成类的时候处理嵌套配置,实现嵌套对象的序列化。
嵌套结构处理示例
import json
# 包含嵌套类的 JSON 配置
nested_config = {
"class_name": "Order",
"attributes": {
"order_id": None,
"user": {
"class_name": "OrderUser",
"attributes": ["username", "address"]
},
"total_price": None
}
}
def parse_config_to_class(config):
# 解析属性配置,处理嵌套类
attrs = {}
for attr_name, attr_value in config["attributes"].items():
if isinstance(attr_value, dict) and "class_name" in attr_value:
# 递归生成嵌套类
nested_class = parse_config_to_class(attr_value)
attrs[attr_name] = nested_class
else:
attrs[attr_name] = attr_value
class_name = config["class_name"]
# 初始化方法,处理嵌套类的实例化
def init(self, **kwargs):
for key, value in kwargs.items():
if key in attrs and isinstance(attrs[key], type):
# 如果属性是类类型,尝试将传入的字典转为类实例
if isinstance(value, dict):
setattr(self, key, attrs[key](**value))
else:
setattr(self, key, value)
else:
setattr(self, key, value)
attrs["__init__"] = init
# 添加 to_dict 方法,处理嵌套对象的序列化
def to_dict(self):
result = {}
for k, v in self.__dict__.items():
if isinstance(v, object) and hasattr(v, "to_dict"):
result[k] = v.to_dict()
else:
result[k] = v
return result
attrs["to_dict"] = to_dict
return type(class_name, (object,), attrs)
# 生成 Order 类
Order = parse_config_to_class(nested_config)
# 创建 Order 实例,传入嵌套的 user 字典
order = Order(
order_id=202401,
user={"username": "李四", "address": "北京市朝阳区"},
total_price=5999.00
)
print(order.to_dict())
# 输出:{"order_id": 202401, "user": {"username": "李四", "address": "北京市朝阳区"}, "total_price": 5999.0}
print(json.dumps(order.to_dict(), ensure_ascii=False))
# 输出:{"order_id": 202401, "user": {"username": "李四", "address": "北京市朝阳区"}, "total_price": 5999.0}
注意事项
- 动态生成的类如果需要修改方法逻辑,可以通过后续给类对象添加属性的方式扩展,不需要重新生成类。
- JSON 配置中如果包含特殊类型(如日期),可以在
to_dict方法中添加类型转换逻辑,避免序列化失败。 - 使用
type生成的类和手动定义的类功能一致,支持继承、方法调用等所有类特性。