所以想象我有類似的東西
class SpecialEnum(Enum):
def do_stuff(self):
# some cool operation
然后有
class MySpecialEnum(SpecialDescriptorEnum):
A = 1
B = 2
然后,我有一個pydantic模型:
class MyModel(BaseModel):
my_field: SpecialEnum
我希望 pydantic 驗證 my_field 是 SpecialEnum 子類的某個實體。但是,pydantic 使用其特殊的列舉驗證器,并改為使用驗證SpecialEnum(field_value),從而導致始終為ValidationError- 因為 SpecialEnum 僅用于提供功能或介面,而不是值。
有什么解決方法嗎?
uj5u.com熱心網友回復:
無需解決方法。您可以通過將特殊__get_validators__類方法添加到基SpecialEnum類來覆寫默認驗證。這是一個完整的作業示例:
from __future__ import annotations
from collections.abc import Callable, Iterator
from enum import Enum
from typing import Any
from pydantic import BaseModel
class SpecialEnum(Enum):
@classmethod
def __get_validators__(cls) -> Iterator[Callable[..., Any]]:
yield cls.validate
@classmethod
def validate(cls, v: SpecialEnum) -> SpecialEnum:
if not isinstance(v, cls):
raise TypeError(f"Must be an instance of `{cls.__name__}`")
return v
def do_stuff(self) -> None:
print("stuff", self)
class MySpecialEnum(SpecialEnum):
A = 1
B = 2
class MyModel(BaseModel):
my_field: SpecialEnum
class Unrelated(Enum):
foo = "foo"
if __name__ == '__main__':
instance = MyModel(my_field=MySpecialEnum.A)
instance.my_field.do_stuff()
# wrong1 = MyModel(my_field=Unrelated.foo) # causes a `ValidationError`
# wrong2 = MyModel(my_field=1) # ALSO causes a `ValidationError`
不過這里有一個警告。通常,您可以定義一些額外的邏輯來接受列舉成員的值,甚至允許成員的名稱并讓驗證器回傳相應的列舉成員本身。(wrong2最后一行的例子。)
但是由于您的驗證方法必須在基類 上定義,SpecialEnum因為這是您用來注釋my_field的方法,因此無法知道要檢查哪個列舉子類來檢查值/名稱。
如果您對此感興趣,您也許可以為此構建一些額外的邏輯,但我認為這只有在您確保所有子類的所有列舉成員SpecialEnum都是不同的情況下才有可能。
希望這可以幫助。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/513408.html
標籤:验证遗产枚举子类书呆子的
上一篇:ExpressJS驗證
下一篇:如何使角度輸入僅接受特定資料
