在 Pydantic 中创建独立的父属性

问题描述 投票:0回答:1

我有一堂这样的活动课:

from datetime import datetime
from typing import Optional

from pydantic import BaseModel, Extra, Field

class Activity(BaseModel, extra=Extra.ignore, frozen=True):
    """Stores ship specific information."""

    id: ActivityId
    owner: Optional[str] = Field(None, min_length=2, max_length=2)
    ship_number: Optional[int] = None
    origin: str = Field(min_length=3, max_length=3)
    origin_sub_location: Optional[str] = None
    destination: str = Field(min_length=3, max_length=3)
    destination_sub_location: Optional[str] = None
    start_time: datetime
    end_time: datetime

然后我想继承该类来创建另一个活动(Lake),继承是临时完成的,但有一个新字段

is_overnight
,这是 Lake Activity 所独有的。还有比这更干净的方法吗?

from datetime import datetime
from typing import Any, Optional

from pydantic import PrivateAttr

class Lake(Activity):
    _is_overnight: bool = PrivateAttr(False)

    def __init__(
        self,
        start_time: datetime,
        location: str,
        is_overnight: bool,
        sub_location: Optional[str] = None,
        **kwargs: Any,
    ):
        # Automatically set end_time, origin, and destination to the same as start_time and location
        super().__init__(
            start_time=start_time,
            end_time=start_time,  # same as start_time for lakes
            origin=location,
            destination=location,
            origin_sub_location=sub_location,
            destination_sub_location=sub_location,
            cancelled=False,
            id=f"LAKE_{location}{sub_location}_{start_time.strftime('%Y-%m-%d %H:%M')}",
            **kwargs,
        )
        self._is_overnight = is_overnight

    @property
    def is_overnight(self) -> bool:
        return self._is_overnight
python inheritance pydantic
1个回答
0
投票

在 pydantic 模型中定义

__init__
直观上似乎是错误的。如果您需要添加新字段,请执行以下操作:

class Lake2(Activity):
    _is_overnight: bool = PrivateAttr(default=False)

如果您想从模型当前实例的字段生成 id,请使用 model_post_init:

class Lake2(Activity):
    _is_overnight: bool = PrivateAttr(default=False)

    def model_post_init(self, __context):
        self.id = (
            f"LAKE_{self.destination}{self.origin_sub_location}_"
            f"{self.start_time.strftime('%Y-%m-%d %H:%M')}"
        )

如果您想添加新字段e。 g。位置,只需在描述符中定义它即可:

class Lake2(Activity):
    _is_overnight: bool = PrivateAttr(default=False)
    location: str = Field(min_length=3, max_length=3)

我不建议像

__init__
论证那样传递它。如果你的child id字段与ActivityId类型不匹配,你也应该重新定义它:

class Lake2(Activity):
    _is_overnight: bool = PrivateAttr(default=False)
    id: str
© www.soinside.com 2019 - 2024. All rights reserved.