You need to enable JavaScript to run this app. Python中如何减少不同类的重复代码,避免重复定义__init__与to_json方法
优惠活动
大模型
产品
解决方案
定价
更多

Python中如何减少不同类的重复代码,避免重复定义__init__与to_json方法

减少重复模型类代码的实现方案

下面给出几种无需引入额外依赖、完全符合需求的原生实现思路,也可以根据自己的需求调整扩展:


方案1:自定义通用基类(最贴合你提到的MyMagicClass预期)

你只要实现一次通用基类,后续所有业务模型类只要继承它、定义字段类型即可,不需要重复写初始化和to_json逻辑:

from typing import Any, Dict

class BaseModel:
    def __init__(self, data_dict: Dict[str, Any]):
        # 遍历子类定义的所有字段,从传入字典取值赋值
        for field in self.__annotations__:
            setattr(self, field, data_dict.get(field))
    
    def to_json(self) -> Dict[str, Any]:
        # 自动生成所有字段的字典返回
        return {field: getattr(self, field) for field in self.__annotations__}

使用示例

from typing import List

# 业务类只需要定义字段类型,没有任何冗余代码
class MyModel(BaseModel):
    x: int
    y: str
    z: List[int]

class MyModel2(BaseModel):
    a: str
    b: int

调用方式完全符合预期:

# 用字典初始化
model = MyModel({"x": 1, "y": "测试", "z": [1,2,3]})
print(model.x) # 输出 1
# 调用通用to_json方法
print(model.to_json()) # 输出 {'x': 1, 'y': '测试', 'z': [1,2,3]}

扩展优化点

  • 可以给字段加默认值:x: int = 0,如果传入字典没有对应字段会自动使用默认值
  • 支持嵌套模型:在__init__中增加类型判断,如果字段类型是BaseModel的子类,自动将传入的字典嵌套初始化
  • 可以增加类型校验逻辑,赋值时自动校验传入值是否符合定义的类型

方案2:基于Python标准库dataclasses实现

如果你不想自己维护基类的初始化逻辑,可以用Python 3.7+自带的dataclasses模块实现:

from dataclasses import dataclass
from typing import Dict, Any, List

@dataclass
class BaseModel:
    @classmethod
    def from_dict(cls, data_dict: Dict[str, Any]):
        return cls(**{k: v for k, v in data_dict.items() if k in cls.__dataclass_fields__})
    
    def to_json(self) -> Dict[str, Any]:
        return {k: getattr(self, k) for k in self.__dataclass_fields__}

使用示例

@dataclass
class MyModel(BaseModel):
    x: int
    y: str
    z: List[int]

# 调用
model = MyModel.from_dict({"x": 2, "y": "示例", "z": [4,5,6]})
print(model.to_json())

这个方案的优势是天然支持dataclass的所有特性,比如自动生成__repr__、__eq__等魔术方法,不用自己额外实现。


方案3:复杂场景可选的第三方方案

如果你的业务需要支持自动类型校验、嵌套模型转换、序列化反序列化等复杂能力,可以直接用pydantic库,天然支持你需要的所有能力,代码更简洁:

from pydantic import BaseModel
from typing import List

class MyModel(BaseModel):
    x: int
    y: str
    z: List[int]

# 直接用字典初始化
model = MyModel(**{"x": 1, "y": "测试", "z": [1,2,3]})
# 自带方法转字典
print(model.dict())

如果不想引入第三方依赖,前面两种原生方案完全可以满足需求。

内容的提问来源于stack exchange,提问作者iElden

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.21 20:54:02