如何在继承的数据类中创建可选字段?

2024-04-20 12:48:46 发布

您现在位置:Python中文网/ 问答频道 /正文

from typing import Optional

@dataclass
class Event:
   id: str
   created_at: datetime
   updated_at: Optional[datetime]
   #updated_at: datetime = field(default_factory=datetime.now)  CASE 1
   #updated_at: Optional[datetime] = None                       CASE 2

@dataclass
class NamedEvent(Event):
  name: str

创建事件实例时,我通常没有updated_at字段。我可以将current time作为默认值传递,也可以在数据库中进行插入时向其添加一个值,并在后续使用对象时获取该值。哪种方式更好? 根据我的理解,在case1和case2中,如果不传递更新的_at字段,我无法创建NamedEvent实例,因为我在name字段中没有默认值


Tags: 实例namefromimporteventtypingdatetimeoptional
1条回答
网友
1楼 · 发布于 2024-04-20 12:48:46

您遇到的潜在问题似乎与here中描述的问题相同。该文章的简短版本是,在函数签名(包括数据类生成的__init__方法)中,强制参数(如NamedEvent的name)不能跟在具有默认值的参数之后(这是定义事件的updated_at行为所必需的)——子字段将始终跟在其父字段之后

因此,要么父类中没有默认值(在本例中不起作用),要么子类的所有字段都需要默认值(这很烦人,有时根本不可行)

我在上面链接的帖子讨论了一些可以应用于解决问题的模式,但是作为更好的选择,您也可以使用第三方包^{},它已经为您解决了这个问题。示例实现可能如下所示:

import pydantic
from datetime import datetime


class Event(pydantic.BaseModel):
    id: str
    created_at: datetime = None
    updated_at: datetime = None

    @pydantic.validator('created_at', pre=True, always=True)
    def default_created(cls, v):
        return v or datetime.now()

    @pydantic.validator('updated_at', pre=True, always=True)
    def default_modified(cls, v, values):
        return v or values['created_at']


class NamedEvent(Event):
    name: str

通过验证器的默认值规范有点麻烦,但总的来说,它是一个非常有用的包,修复了您在使用数据类时遇到的许多缺点,以及其他一些缺点

使用类定义,可以如下方式创建NamedEvent的实例:

>>> NamedEvent(id='1', name='foo')
NamedEvent(id='1', created_at=datetime.datetime(2020, 5, 2, 18, 50, 12, 902732), updated_at=datetime.datetime(2020, 5, 2, 18, 50, 12, 902732), name='foo')

相关问题 更多 >