You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python中如何在DomainA与ServiceA类间拷贝属性?求复用方案

跨类实例属性互拷贝的第三方库推荐

我需要实现ServiceA类与DomainA类实例之间的属性值互拷贝,目前自己写的Convertor类方案不够灵活、复用性差,想找现成可用的第三方库/模块。注意:需求不是同一类不同实例的深浅拷贝。

当前实现代码:

class ServiceA(object):
    def __init__(self, api_name=None, author=None, region=None):
        self.api_name = api_name
        self.author = author
        self.region = region

class DomainA(models.Model):
    api_name = models.CharField(max_length=512, blank=True, null=True)
    author = models.CharField(max_length=256, blank=True, null=True)
    region = models.CharField(max_length=256, blank=True, null=True)

# 自己实现的转换类
class Convertor:
    def __init__(self):
        super(Convertor, self).__init__()
    
    def BoToDo(self, bo: ServiceA) -> DomainA:
        do = DomainA()
        if bo.api_name is not None:
            do.api_name = bo.api_name
        if bo.author is not None:
            do.author = bo.author
        if bo.region is not None:
            do.region = bo.region

        return do

    def DoToBo(self, do: DomainA) -> ServiceA:
        pass

推荐的第三方库方案:

1. cattrs(配合attrs)

cattrs是专门处理Python对象转换的工具,对普通类和attrs装饰的类都支持,能自动匹配同名属性,也支持自定义映射规则。

安装:

pip install attrs cattrs

用法示例:

from cattrs import structure, unstructure

# ServiceA 转 DomainA
def bo_to_do(bo: ServiceA) -> DomainA:
    bo_dict = unstructure(bo)
    return structure(bo_dict, DomainA)

# DomainA 转 ServiceA
def do_to_bo(do: DomainA) -> ServiceA:
    do_dict = unstructure(do)
    return structure(do_dict, ServiceA)

如果存在属性名不一致的情况,还可以注册自定义转换器,灵活性拉满。

2. pydantic

pydantic主打数据验证,但也能便捷实现跨类属性拷贝,支持字段重命名、默认值处理等场景。

安装:

pip install pydantic

用法示例:

from pydantic import BaseModel

# 定义中间层Schema(也可直接用现有类转换)
class CommonSchema(BaseModel):
    api_name: str | None = None
    author: str | None = None
    region: str | None = None

    class Config:
        orm_mode = True  # 支持从Django Model这类ORM模型读取数据

# ServiceA 转 DomainA
def bo_to_do(bo: ServiceA) -> DomainA:
    schema = CommonSchema(**vars(bo))
    return DomainA(**schema.dict(exclude_unset=True))

# DomainA 转 ServiceA
def do_to_bo(do: DomainA) -> ServiceA:
    schema = CommonSchema.from_orm(do)
    return ServiceA(**schema.dict(exclude_unset=True))

exclude_unset参数会忽略未赋值的属性,和你原来的if判断逻辑完全一致。

3. mapper

这是一个轻量对象映射库,支持显式定义字段映射规则,适合需要精细控制转换逻辑的场景。

安装:

pip install mapper

用法示例:

from mapper import Mapper

# 创建映射器,同名属性可省略映射规则
mapper = Mapper()
mapper.add_mapping(ServiceA, DomainA)
mapper.add_mapping(DomainA, ServiceA)

# ServiceA 转 DomainA
def bo_to_do(bo: ServiceA) -> DomainA:
    return mapper.map(bo, DomainA)

# DomainA 转 ServiceA
def do_to_bo(do: DomainA) -> ServiceA:
    return mapper.map(do, ServiceA)

如果有属性名不同的情况,直接在add_mapping里传入{"源字段名": "目标字段名"}即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 00:22:09