Model类
Python泛型类
TypeVar 是一个泛型类型变量,使用 bound 参数来限制所生成的类型的继承关系。
from typing import Generic, TypeVar
from pydantic import BaseModel
# T只能是BaseModel或者int类型
TypeX = TypeVar('TypeX', BaseModel, int)
class BaseClass(BaseModel, Generic[TypeX]):
X: TypeX
# 子类必须也继承Generic[TypeX]
class ChildClass(BaseClass[TypeX], Generic[TypeX]):
# Inherit from Generic[TypeX]
pass
Model.construct跳过验证
使用默认构造函数创建对象会对属性进行校验,如果我们不希望进行校验,可以使用model.construct方法,使用该方法需要注意以下几点
- 既然跳过了数据验证,pydantic也会跳过将字典对象转化为模型的步骤,意味着对于对象类型的属性,我们提供给model_construct的需要是对象类型。
- 不支持递归构造,只会解析一层。
- 如果传入了多余的属性并且extra设置为allow,多余的属性被存储到__pydantic_extra__。
- 如果模型存在私有属性,__pydantic_private__字典的初始化与调用__init__方法一样。
- 使用model_construct不会调用任何__init__方法。
综上,非必要不建议使用该方法。
动态创建Model类
根据运行时信息的不同,我们可能有不同的模型属性和校验规则,这个时候就需要动态创建Model类了。
from pydantic import BaseModel, create_model
DynamicFoobarModel = create_model(
'DynamicFoobarModel', foo=(str, ...), bar=(int, 123)
)
class StaticFoobarModel(BaseModel):
foo: str
bar: int = 123
def username_alphanumeric(cls, v):
assert v.isalnum(), 'must be alphanumeric'
return v
# 定义校验器
validators = {
'username_validator': field_validator('username')(username_alphanumeric)
}
UserModel = create_model(
'UserModel', username=(str, ...), __validators__=validators,
# 父类
__base__=StaticFooBarModel
)
类属性和私有属性
- 对象可访问类属性,但不可修改
- 私有属性必须以下划线开头,不会被序列化
class Model(BaseModel):
x: int = 2
y: ClassVar[int] = 1
_processed_at: datetime = PrivateAttr(default_factory=datetime.now)
_secret_value: str
def __init__(self, **data):
super().__init__(**data)
# this could also be done with default_factory
self._secret_value = randint(1, 5)
m = Model()
print(m)
print(m.y)
print(Model.y)
m.y += 1 # error
Q.E.D.