跳转至

Pydantic Company

我们根据我认为导致 Pydantic 成功的原则创办了一家公司。

公司公告中了解更多信息.

模型配置

pydantic 的行为可以通过模型上的 Config 类或 pydantic 数据类来控制。

from pydantic import BaseModel, ValidationError


class Model(BaseModel):
    v: str

    class Config:
        max_anystr_length = 10
        error_msg_templates = {
            'value_error.any_str.max_length': 'max_length:{limit_value}',
        }


try:
    Model(v='x' * 20)
except ValidationError as e:
    print(e)
    """
    1 validation error for Model
    v
      max_length:10 (type=value_error.any_str.max_length; limit_value=10)
    """

(这个脚本是完整的,它应该“按原样”运行)

此外,您可以将配置选项指定为模型类 kwargs:

from pydantic import BaseModel, ValidationError, Extra


class Model(BaseModel, extra=Extra.forbid):
    a: str


try:
    Model(a='spam', b='oh no')
except ValidationError as e:
    print(e)
    """
    1 validation error for Model
    b
      extra fields not permitted (type=value_error.extra)
    """

(这个脚本是完整的,它应该“按原样”运行)

同样,如果使用@dataclass装饰器:

from datetime import datetime

from pydantic import ValidationError
from pydantic.dataclasses import dataclass


class MyConfig:
    max_anystr_length = 10
    validate_assignment = True
    error_msg_templates = {
        'value_error.any_str.max_length': 'max_length:{limit_value}',
    }


@dataclass(config=MyConfig)
class User:
    id: int
    name: str = 'John Doe'
    signup_ts: datetime = None


user = User(id='42', signup_ts='2032-06-21T12:00')
try:
    user.name = 'x' * 20
except ValidationError as e:
    print(e)
    """
    1 validation error for User
    name
      max_length:10 (type=value_error.any_str.max_length; limit_value=10)
    """

(这个脚本是完整的,它应该“按原样”运行)

可选项(Options)

title
生成的 JSON 模式的标题
anystr_strip_whitespace
是否去除 str & byte 类型的前导和尾随空格(默认值:False
anystr_upper
是否将 str 和 byte 类型的所有字符都设为大写(默认值:False
anystr_lower
是否将 str 和 byte 类型的所有字符都设为小写(默认值:False
min_anystr_length
str 和 byte 类型的最小长度(默认值:0
max_anystr_length
str & byte 类型的最大长度(默认值:None
validate_all
是否验证字段默认值(默认值:False
extra
在模型初始化期间是否忽略、允许或禁止额外的属性。 接受“ignore”“allow”“forbid”的字符串值,或“Extra”枚举的值(默认值:“Extra.ignore”)。 如果包含额外的属性,'forbid' 将导致验证失败,'ignore' 将默默地忽略任何额外的属性,'allow' 将属性分配给模型。
allow_mutation
模型是否是伪不可变的,即是否允许 __setattr__(默认值:True

frozen

Warning

此参数处于测试阶段

设置 frozen=True 会执行 allow_mutation=False 所做的一切,还会为模型生成 __hash__() 方法。 如果所有属性都是可散列的,这使得模型的实例可能是可散列的。 (默认值:False
use_enum_values
是否使用枚举的value属性而不是原始枚举来填充模型。 如果您想稍后序列化 model.dict()(默认值:False),这可能很有用
fields
包含每个字段的架构信息的dict; 这等同于使用 Field,除非已经通过注释或 Field 类定义了一个字段,在这种情况下只有 aliasincludeexcludemin_length, max_length, regex, gt, lt, gt, le, multiple_of, max_digits, decimal_places, min_items, max_items, unique_itemsallow_mutation 可以设置(例如你不能设置 default_factory 的默认值)(默认值:None
validate_assignment
是否对属性的_assignment_执行验证(默认值:False
allow_population_by_field_name
别名字段是否可以由模型属性给出的名称以及别名(默认值:False)填充

Note

此配置设置的名称在 v1.0 中从allow_population_by_alias更改为allow_population_by_field_name

error_msg_templates
用于覆盖默认错误消息模板的 dict。 传入一个字典,其中的键与您要覆盖的错误消息匹配(默认值:{}
arbitrary_types_allowed
是否允许字段的任意用户类型(通过检查值是否是该类型的实例来验证它们)。 如果为False,将在模型声明时引发RuntimeError(默认值:False)。 请参阅 Field Types 中的示例。
orm_mode
是否允许使用 ORM 模式
getter_dict
在分解任意类进行验证时使用的自定义类(应继承自 GetterDict),与 orm_mode 一起使用; 参见 数据绑定
alias_generator
一个可调用的,它接受一个字段名并为其返回一个别名; 参见 专用部分
keep_untouched
模型默认值的类型元组(例如描述符),在模型创建期间不应更改并且不会包含在模型模式中。 注意:这意味着模型上具有 这种类型的默认值 而不是 这种类型的注释 的属性将被单独保留。
schema_extra
用于扩展/更新生成的 JSON Schema 的 dict,或用于对其进行后处理的可调用对象; 参见 schema 自定义
json_loads
用于解码 JSON 的自定义函数; 参见 自定义 JSON(反)序列化
json_dumps
用于编码 JSON 的自定义函数; 参见 自定义 JSON(反)序列化
json_encoders
用于自定义类型编码为 JSON 的方式的 dict; 参见 JSON 序列化
underscore_attrs_are_private
是否将任何下划线非类属性视为私有,或保持原样; 参见 私有模型属性
copy_on_model_validation
字符串文字来控制模型实例在验证过程中的处理方式,使用以下方法(有关此字段更改的完整讨论,请参阅 #4093 :
  • 'none' - 模型不会在验证时被复制,它们只是保持“不变(untouched)”
  • 'shallow' - 模型是浅拷贝的,这是默认的
  • 'deep' - 模型被深度复制
smart_union
pydantic 是否应该尝试检查 Union 中的所有类型以防止不希望的强制转换; 请参阅 专用部分
post_init_call
stdlib 数据类 __post_init__ 是否应该在解析和验证之前(默认行为值为 'before_validation')或之后(值为 'after_validation')运行转换
allow_inf_nan
是否允许无穷大(+inf-inf)和 NaN 值浮动字段,默认为 True,设置为 False 以兼容 JSON,参见[#3994](https:// github.com/pydantic/pydantic/pull/3994)了解更多详情,添加于V1.10

全局改变行为(Change behaviour globally)

如果您希望全局更改 pydantic 的行为,您可以使用自定义 Config 创建自己的自定义 BaseModel,因为配置是继承的

from pydantic import BaseModel as PydanticBaseModel


class BaseModel(PydanticBaseModel):
    class Config:
        arbitrary_types_allowed = True


class MyClass:
    """A random class"""


class Model(BaseModel):
    x: MyClass

(这个脚本是完整的,它应该“按原样”运行)

别名生成器(Alias Generator)

如果数据源字段名称与您的代码风格不匹配(例如 CamelCase 字段),您可以使用 alias_generator 自动生成别名:

from pydantic import BaseModel


def to_camel(string: str) -> str:
    return ''.join(word.capitalize() for word in string.split('_'))


class Voice(BaseModel):
    name: str
    language_code: str

    class Config:
        alias_generator = to_camel


voice = Voice(Name='Filiz', LanguageCode='tr-TR')
print(voice.language_code)
#> tr-TR
print(voice.dict(by_alias=True))
#> {'Name': 'Filiz', 'LanguageCode': 'tr-TR'}

(这个脚本是完整的,它应该“按原样”运行)

这里的驼峰案例指的是 “大驼峰案例” 又名帕斯卡案例,例如 驼峰式。 如果您想改用小驼峰式,例如 camelCase,而是使用 to_lower_camel 函数。

别名优先(Alias Precedence)

Warning

别名优先级逻辑在 v1.4 中发生了变化,以解决以前版本中的错误和意外行为。 在某些情况下,这可能代表一个重大变化,请参阅 #1178 和下面的优先顺序了解详细信息。

在一个字段的别名可能定义在多个地方的情况下,选择的值确定如下(按优先级降序排列):

  1. 通过 Field(..., alias=<alias>) 直接在模型上设置
  2. Config.fields 中定义,直接在模型上
  3. 在父模型上通过 Field(..., alias=<alias>) 设置
  4. 在父模型的Config.fields中定义
  5. alias_generator 生成,无论它是在模型上还是在父级上

Note

这意味着在子模型上定义的 alias_generator 不会 优先于在父模型中的字段上定义的别名。

例如:

from pydantic import BaseModel, Field


class Voice(BaseModel):
    name: str = Field(None, alias='ActorName')
    language_code: str = None
    mood: str = None


class Character(Voice):
    act: int = 1

    class Config:
        fields = {'language_code': 'lang'}

        @classmethod
        def alias_generator(cls, string: str) -> str:
            # this is the same as `alias_generator = to_camel` above
            return ''.join(word.capitalize() for word in string.split('_'))


print(Character.schema(by_alias=True))
"""
{
    'title': 'Character',
    'type': 'object',
    'properties': {
        'ActorName': {'title': 'Actorname', 'type': 'string'},
        'lang': {'title': 'Lang', 'type': 'string'},
        'Mood': {'title': 'Mood', 'type': 'string'},
        'Act': {'title': 'Act', 'default': 1, 'type': 'integer'},
    },
}
"""

(这个脚本是完整的,它应该“按原样”运行)

智能联合(Smart Union)

默认情况下,如 此处 所述,pydantic 尝试按照 Union 的顺序验证(并强制执行)。 所以有时候你可能会有意想不到的强制数据。

from typing import Union

from pydantic import BaseModel


class Foo(BaseModel):
    pass


class Bar(BaseModel):
    pass


class Model(BaseModel):
    x: Union[str, int]
    y: Union[Foo, Bar]


print(Model(x=1, y=Bar()))
#> x='1' y=Foo()
from pydantic import BaseModel


class Foo(BaseModel):
    pass


class Bar(BaseModel):
    pass


class Model(BaseModel):
    x: str | int
    y: Foo | Bar


print(Model(x=1, y=Bar()))
#> x='1' y=Foo()

(这个脚本是完整的,它应该“按原样”运行)

为防止这种情况,您可以启用 Config.smart_unionPydantic 然后会在尝试强制之前检查所有允许的类型。 要知道这当然会更慢,尤其是当你的 Union 很大的时候。

from typing import Union

from pydantic import BaseModel


class Foo(BaseModel):
    pass


class Bar(BaseModel):
    pass


class Model(BaseModel):
    x: Union[str, int]
    y: Union[Foo, Bar]

    class Config:
        smart_union = True


print(Model(x=1, y=Bar()))
#> x=1 y=Bar()
from pydantic import BaseModel


class Foo(BaseModel):
    pass


class Bar(BaseModel):
    pass


class Model(BaseModel):
    x: str | int
    y: Foo | Bar

    class Config:
        smart_union = True


print(Model(x=1, y=Bar()))
#> x=1 y=Bar()

(这个脚本是完整的,它应该“按原样”运行)

Warning

请注意,此选项尚不支持复合类型(例如,区分 List[int]List[str])。 一旦在 pydantic 中添加严格模式,此选项将得到进一步改进,并且可能成为 v2 中的默认行为!

from typing import List, Union

from pydantic import BaseModel


class Model(BaseModel, smart_union=True):
    x: Union[List[str], List[int]]


# Expected coercion
print(Model(x=[1, '2']))
#> x=['1', '2']

# Unexpected coercion
print(Model(x=[1, 2]))
#> x=['1', '2']
from typing import Union

from pydantic import BaseModel


class Model(BaseModel, smart_union=True):
    x: Union[list[str], list[int]]


# Expected coercion
print(Model(x=[1, '2']))
#> x=['1', '2']

# Unexpected coercion
print(Model(x=[1, 2]))
#> x=['1', '2']
from pydantic import BaseModel


class Model(BaseModel, smart_union=True):
    x: list[str] | list[int]


# Expected coercion
print(Model(x=[1, '2']))
#> x=['1', '2']

# Unexpected coercion
print(Model(x=[1, 2]))
#> x=['1', '2']

(这个脚本是完整的,它应该“按原样”运行)