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

嵌套dataclass创建问题:pricing字段未自动填充如何解决?

嵌套Dataclass中pricing字段未自动填充的问题分析与解决

你编写了嵌套dataclass代码,期望LineItem的__post_init__方法自动填充pricing字段,但实际输出里该字段缺失,且lineItems仍是字典列表而非LineItem实例。

错误原因

  1. 类型标注不触发自动转换:Python的类型标注仅用于代码提示和静态检查,不会自动将字典转换为LineItem实例。你传入的lineItems是字典列表,即使标注为List[LineItem],Python也不会自动处理。
  2. 实例创建未替换原数据:Order的__post_init__中,你创建了LineItem(**l)实例,但没有将这些实例替换掉原lineItems列表里的字典,相当于白创建了实例,原列表内容完全没变化。

修正方案

修改Order类的__post_init__方法,将字典列表转换为LineItem实例列表并赋值回self.lineItems:

from dataclasses import dataclass, field
import datetime
from typing import List


@dataclass
class LineItem:
    displayName: str
    compareAtPrice: float
    discountedPrice: float
    pricing: str = field(init=False)

    def __post_init__(self):
        self.pricing = (
            "regular" if self.compareAtPrice == self.discountedPrice else "on sale"
        )


@dataclass
class Order:
    createdAt: datetime.datetime  # 修正类型标注,匹配实际传入的datetime实例
    lineItems: List[LineItem]

    def __post_init__(self):
        # 将字典列表转换为LineItem实例列表并替换原属性
        self.lineItems = [LineItem(**item) for item in self.lineItems]


data = {
    "createdAt": datetime.datetime.now(),
    "lineItems": [
        {
            "displayName": "lineitem 1",
            "compareAtPrice": 28.1,
            "discountedPrice": 28.1,
        },
        {
            "displayName": "lineitem 2",
            "compareAtPrice": 88.1,
            "discountedPrice": 78.1,
        },
    ],
}

print(Order(**data))

修正后输出

运行后会得到包含pricing字段的LineItem实例列表:

Order(createdAt=datetime.datetime(2023, 3, 9, 17, 18, 40, 136535), lineItems=[LineItem(displayName='lineitem 1', compareAtPrice=28.1, discountedPrice=28.1, pricing='regular'), LineItem(displayName='lineitem 2', compareAtPrice=88.1, discountedPrice=78.1, pricing='on sale')])

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 17:22:16