簡體   English   中英

如何在繼承的數據類中創建可選字段?

[英]How to create an optional field in a dataclass that is inherited?

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作為默認值傳遞,也可以在插入數據庫時為其添加一個值,並在 object 的后續使用中獲取它。 哪個是更好的方法? 根據我的理解,如果不傳遞 case1 和 case2 中的 updated_at字段,我無法創建NamedEvent實例,因為我在 name 字段中沒有默認值。

您遇到的潛在問題似乎與此處描述的問題相同。 The short version of that post is that in a function signature (including the dataclass-generated __init__ method), obligatory arguments (like NamedEvent's name ) can not follow after arguments with default values (which are necessary to define the behavior of Event's updated_at ) -孩子的領域將永遠跟隨其父母的領域。

因此,要么您的父 class 中沒有默認值(在這種情況下不起作用),要么您孩子的所有字段都需要默認值(這很煩人,有時根本不可行)。

我在上面鏈接的帖子討論了一些可以用來解決問題的模式,但作為更好的選擇,您還可以使用第三方 package pydantic ,它已經為您解決了這個問題。 示例實現可能如下所示:

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

通過驗證器的默認值規范有點麻煩,但總的來說,它是一個非常有用的 package,它修復了您在使用數據類時遇到的許多缺點,以及更多。

使用 class 定義,可以像這樣創建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')

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM