文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

python库pydantic怎么用

2023-06-29 17:36

关注

这篇文章主要介绍了python库pydantic怎么用,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。

一、简介

pydantic 库是 python 中用于数据接口定义检查与设置管理的库。

pydantic 在运行时强制执行类型提示,并在数据无效时提供友好的错误。

它具有如下优点:

二、安装

pip install pydantic

要测试 pydantic 是否已编译,请运行:

import pydanticprint('compiled:', pydantic.compiled)

支持使用dotenv文件获取配置,需要安装 python-dotenv

pip install pydantic[dotenv]

三、常见模型

pydantic中定义对象都是通过模型的,你可以认为模型就是类型语言中的类型。

1、BaseModel 基本模型

from pydantic import BaseModelclass User(BaseModel):    id: int    name = 'Jane Doe'

上面的例子,定义了一个User模型,继承自BaseModel,有2个字段,id是一个整数并且是必需的,name是一个带有默认值的字符串并且不是必需的

实例化使用:

user = User(id='123')

实例化将执行所有解析和验证,如果有错误则会触发 ValidationError 报错。

模型具有以下属性:

2、递归模型

可以使用模型本身作为注释中的类型来定义更复杂的数据结构。

from typing import Listfrom pydantic import BaseModelclass Foo(BaseModel):    count: int    size: float = Noneclass Bar(BaseModel):    apple = 'x'    banana = 'y'class Spam(BaseModel):    foo: Foo    bars: List[Bar]

3、GenericModel 通用模型(泛型):

使用 typing.TypeVar 的实例作为参数,传递给 typing.Generic,然后在继承了pydantic.generics.GenericModel 的模型中使用:

from typing import Generic, TypeVar, Optional, Listfrom pydantic import BaseModel, validator, ValidationErrorfrom pydantic.generics import GenericModelDataT = TypeVar('DataT')class Error(BaseModel):    code: int    message: strclass DataModel(BaseModel):    numbers: List[int]    people: List[str]class Response(GenericModel, Generic[DataT]):    data: Optional[DataT]    error: Optional[Error]    @validator('error', always=True)    def check_consistency(cls, v, values):        if v is not None and values['data'] is not None:            raise ValueError('must not provide both data and error')        if v is None and values.get('data') is None:            raise ValueError('must provide data or error')        return vdata = DataModel(numbers=[1, 2, 3], people=[])error = Error(code=404, message='Not found')print(Response[int](data=1))#> data=1 error=Noneprint(Response[str](data='value'))#> data='value' error=Noneprint(Response[str](data='value').dict())#> {'data': 'value', 'error': None}print(Response[DataModel](data=data).dict())"""{    'data': {'numbers': [1, 2, 3], 'people': []},    'error': None,}"""print(Response[DataModel](error=error).dict())"""{    'data': None,    'error': {'code': 404, 'message': 'Not found'},}"""try:    Response[int](data='value')except ValidationError as e:    print(e)    """    2 validation errors for Response[int]    data      value is not a valid integer (type=type_error.integer)    error      must provide data or error (type=value_error)    """

create_model 动态模型

在某些情况下,直到运行时才知道模型的结构。为此 pydantic 提供了create_model允许动态创建模型的方法。

from pydantic import BaseModel, create_modelDynamicFoobarModel = create_model('DynamicFoobarModel', foo=(str, ...), bar=123)

四、常用类型

五、验证器

使用validator装饰器可以实现自定义验证和对象之间的复杂关系。

from pydantic import BaseModel, ValidationError, validatorclass UserModel(BaseModel):    name: str    username: str    password1: str    password2: str    @validator('name')    def name_must_contain_space(cls, v):        if ' ' not in v:            raise ValueError('must contain a space')        return v.title()    @validator('password2')    def passwords_match(cls, v, values, **kwargs):        if 'password1' in values and v != values['password1']:            raise ValueError('passwords do not match')        return v    @validator('username')    def username_alphanumeric(cls, v):        assert v.isalnum(), 'must be alphanumeric'        return vuser = UserModel(    name='samuel colvin',    username='scolvin',    password1='zxcvbn',    password2='zxcvbn',)print(user)#> name='Samuel Colvin' username='scolvin' password1='zxcvbn' password2='zxcvbn'try:    UserModel(        name='samuel',        username='scolvin',        password1='zxcvbn',        password2='zxcvbn2',    )except ValidationError as e:    print(e)    """    2 validation errors for UserModel    name      must contain a space (type=value_error)    password2      passwords do not match (type=value_error)    """

关于验证器的一些注意事项:

from typing import Listfrom pydantic import BaseModel, ValidationError, validatorclass ParentModel(BaseModel):    names: List[str]class ChildModel(ParentModel):    @validator('names', each_item=True)    def check_names_not_empty(cls, v):        assert v != '', 'Empty strings are not allowed.'        return v# This will NOT raise a ValidationError because the validator was not calledtry:    child = ChildModel(names=['Alice', 'Bob', 'Eve', ''])except ValidationError as e:    print(e)else:    print('No ValidationError caught.')    #> No ValidationError caught.class ChildModel2(ParentModel):    @validator('names')    def check_names_not_empty(cls, v):        for name in v:            assert name != '', 'Empty strings are not allowed.'        return vtry:    child = ChildModel2(names=['Alice', 'Bob', 'Eve', ''])except ValidationError as e:    print(e)    """    1 validation error for ChildModel2    names      Empty strings are not allowed. (type=assertion_error)    """
from pydantic import BaseModel, validatordef normalize(name: str) -> str:    return ' '.join((word.capitalize()) for word in name.split(' '))class Producer(BaseModel):    name: str    # validators    _normalize_name = validator('name', allow_reuse=True)(normalize)class Consumer(BaseModel):    name: str    # validators    _normalize_name = validator('name', allow_reuse=True)(normalize)

六、配置

如果您创建一个继承自BaseSettings的模型,模型初始化程序将尝试通过从环境中读取,来确定未作为关键字参数传递的任何字段的值。(如果未设置匹配的环境变量,则仍将使用默认值。)

这使得很容易:

from typing import Setfrom pydantic import (    BaseModel,    BaseSettings,    PyObject,    RedisDsn,    PostgresDsn,    Field,)class SubModel(BaseModel):    foo = 'bar'    apple = 1class Settings(BaseSettings):    auth_key: str    api_key: str = Field(..., env='my_api_key')    redis_dsn: RedisDsn = 'redis://user:pass@localhost:6379/1'    pg_dsn: PostgresDsn = 'postgres://user:pass@localhost:5432/foobar'    special_function: PyObject = 'math.cos'    # to override domains:    # export my_prefix_domains='["foo.com", "bar.com"]'    domains: Set[str] = set()    # to override more_settings:    # export my_prefix_more_settings='{"foo": "x", "apple": 1}'    more_settings: SubModel = SubModel()    class Config:        env_prefix = 'my_prefix_'  # defaults to no prefix, i.e. ""        fields = {            'auth_key': {                'env': 'my_auth_key',            },            'redis_dsn': {                'env': ['service_redis_dsn', 'redis_url']            }        }print(Settings().dict())"""{    'auth_key': 'xxx',    'api_key': 'xxx',    'redis_dsn': RedisDsn('redis://user:pass@localhost:6379/1',scheme='redis', user='user', password='pass', host='localhost',host_type='int_domain', port='6379', path='/1'),    'pg_dsn': PostgresDsn('postgres://user:pass@localhost:5432/foobar',scheme='postgres', user='user', password='pass', host='localhost',host_type='int_domain', port='5432', path='/foobar'),    'special_function': <built-in function cos>,    'domains': set(),    'more_settings': {'foo': 'bar', 'apple': 1},}"""

支持 Dotenv 文件设置变量,pydantic 有两种方式加载它:

class Settings(BaseSettings):    ...    class Config:        env_file = '.env'        env_file_encoding = 'utf-8'

或者

settings=Settings(_env_file='prod.env',_env_file_encoding='utf-8')

即使使用 dotenv 文件,pydantic 仍会读取环境变量,环境变量将始终优先于从 dotenv 文件加载的值。

pydantic 支持设置敏感信息文件,同样有2种方式加载:

class Settings(BaseSettings):    ...    database_password: str    class Config:        secrets_dir = '/var/run'

或者:

settings = Settings(_secrets_dir='/var/run')

即使使用 secrets 目录,pydantic仍会从 dotenv 文件或环境中读取环境变量,dotenv 文件和环境变量将始终优先于从 secrets 目录加载的值。

七、与 mypy 一起使用

Pydantic 附带了一个 mypy 插件,向 mypy 添加了许多重要的特定于 pydantic 的功能,以提高其对代码进行类型检查的能力。

例如以下脚本:

from datetime import datetimefrom typing import List, Optionalfrom pydantic import BaseModel, NoneStrclass Model(BaseModel):    age: int    first_name = 'John'    last_name: NoneStr = None    signup_ts: Optional[datetime] = None    list_of_ints: List[int]m = Model(age=42, list_of_ints=[1, '2', b'3'])print(m.middle_name)  # not a model field!Model()  # will raise a validation error for age and list_of_ints

在没有任何特殊配置的情况下,mypy 会捕获其中一个错误:

13: error: "Model" has no attribute "middle_name"

启用插件后,它会同时捕获:

13: error: "Model" has no attribute "middle_name"16: error: Missing named argument "age" for "Model"16: error: Missing named argument "list_of_ints" for "Model"

要启用该插件,只需添加pydantic.mypy到mypy 配置文件中的插件列表:

[mypy]plugins = pydantic.mypy

要更改插件设置的值,请在 mypy 配置文件中创建一个名为 的部分[pydantic-mypy],并为要覆盖的设置添加键值对:

[mypy]plugins = pydantic.mypyfollow_imports = silentwarn_redundant_casts = Truewarn_unused_ignores = Truedisallow_any_generics = Truecheck_untyped_defs = Trueno_implicit_reexport = True# for strict mypy: (this is the tricky one :-))disallow_untyped_defs = True[pydantic-mypy]init_forbid_extra = Trueinit_typed = Truewarn_required_dynamic_aliases = Truewarn_untyped_fields = True

感谢你能够认真阅读完这篇文章,希望小编分享的“python库pydantic怎么用”这篇文章对大家有帮助,同时也希望大家多多支持编程网,关注编程网行业资讯频道,更多相关知识等着你来学习!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯