我有一堂这样的活动课:
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
在 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