我正在使用 pydantic 進行模式驗證,當將任何額外欄位添加到未定義的模式時,我想拋出一個錯誤。
from typing import Literal, Union
from pydantic import BaseModel, Field, ValidationError
class Cat(BaseModel):
pet_type: Literal['cat']
meows: int
class Dog(BaseModel):
pet_type: Literal['dog']
barks: float
class Lizard(BaseModel):
pet_type: Literal['reptile', 'lizard']
scales: bool
class Model(BaseModel):
pet: Union[Cat, Dog, Lizard] = Field(..., discriminator='pet_type')
n: int
print(Model(pet={'pet_type': 'dog', 'barks': 3.14, 'eats': 'biscuit'}, n=1))
""" try:
Model(pet={'pet_type': 'dog'}, n=1)
except ValidationError as e:
print(e) """
在上面的代碼中,我添加了eats未定義的欄位。應用了 pydantic 驗證,并洗掉了我定義的額外值作為回應。我想拋出一個錯誤說eats is not allowed for Dog或類似的東西。有沒有辦法做到這一點?
有沒有可能我們可以直接提供輸入而不是pet物件?
print(Model({'pet_type': 'dog', 'barks': 3.14, 'eats': 'biscuit', n=1})). 我試過沒有descriminator,但缺少與pet_type. 有人可以指導我如何實作其中任何一個嗎?
uj5u.com熱心網友回復:
您可以使用類中的extra欄位在模型初始化期間禁止額外的屬性(默認情況下,將忽略額外的屬性)。Config
例如:
from pydantic import BaseModel, Extra
class Pet(BaseModel):
name: str
class Config:
extra = Extra.forbid
data = {
"name": "some name",
"some_extra_field": "some value",
}
my_pet = Pet.parse_obj(data) # <- effectively the same as Pet(**pet_data)
將提出VaidationError:
ValidationError: 1 validation error for Pet
some_extra_field
extra fields not permitted (type=value_error.extra)
當模型“嵌套”時也可以作業,例如:
class PetModel(BaseModel):
my_pet: Pet
n: int
pet_data = {
"my_pet": {"name": "Some Name", "invalid_field": "some value"},
"n": 5,
}
pet_model = PetModel.parse_obj(pet_data)
# Effectively the same as
# pet_model = PetModel(my_pet={"name": "Some Name", "invalid_field": "some value"}, n=5)
將提出:
ValidationError: 1 validation error for PetModel
my_pet -> invalid_field
extra fields not permitted (type=value_error.extra)
uj5u.com熱心網友回復:
Pydantic 用于使用模式驗證您的輸入。在您的情況下,您想要洗掉其驗證功能之一。
我認為你應該創建一個繼承自的新類BaseModel
class ModifiedBaseModel(BaseModel):
def __init__(__pydantic_self__, **data: Any) -> None:
registered, not_registered = __pydantic_self__.filter_data(data)
super().__init__(**registered)
for k, v in not_registered.items():
__pydantic_self__.__dict__[k] = v
@classmethod
def filter_data(cls, data):
registered_attr = {}
not_registered_attr = {}
annots = cls.__annotations__
for k, v in data.items():
if k in annots:
registered_attr[k] = v
else:
not_registered_attr[k] = v
return registered_attr, not_registered_attr
然后創建您的驗證類
class Cat(ModifiedBaseModel):
pet_type: Literal['cat']
meows: int
現在您可以創建一個新的Cat而不必擔心未定義的屬性。像這樣
my_cat = Cat(pet_type='cat', meows=3, name='blacky', age=3)
第二個問題,直接輸入dict你可以使用雙星號**
Dog(**my_dog_data_in_dict)
或者
Dog(**{'pet_type': 'dog', 'barks': 3.14, 'eats': 'biscuit', n=1})
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/462067.html
上一篇:引數型別'字串?函式(字串)'不能分配給引數型別'字串?函式(字串?)?
下一篇:Java中的命令注入
