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
データベースに挿入するときにデフォルト値として渡すか、値を追加して、オブジェクトの後続の使用でフェッチすることができます。どちらが良い方法ですか?私の理解では、nameフィールドにデフォルト値がないため、case1とcase2のupdated_atフィールドを渡さずにNamedEvent
インスタンスを作成することはできません。
あなたが抱えている根本的な問題は、ここで説明されているものと同じようです。その投稿の短いバージョンは、関数シグネチャ(データクラスで生成された__init__
メソッドを含む)では、必須の引数(NamedEventのようなname
)はデフォルト値(イベントの動作を定義するために必要)を持つ引数の後に続くことができないということですupdated_at
-子のフィールド常にその親のものの後に続きます。
したがって、親クラスにデフォルト値がない(この場合は機能しません)か、すべての子のフィールドにデフォルト値が必要です(これは煩わしく、場合によっては単に実行不可能です)。
上でリンクした投稿では、問題を解決するために適用できるいくつかのパターンについて説明していますが、より良い代替手段として、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
バリデーターによるデフォルト値の指定は少し面倒ですが、全体として、データクラスを使用するときに遭遇する多くの欠点に加えて、いくつかの欠点を修正する非常に便利なパッケージです。
クラス定義を使用して、のインスタンスを次の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')
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加