ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

pydantic字段类型

2022-06-15 18:00:38  阅读:272  来源: 互联网

标签:print 字段 BaseModel 类型 import Model type class pydantic


1.复合类型

  • Union,支持将多种类型作为可选项
from uuid import UUID
from typing import Union
from pydantic import BaseModel


class User(BaseModel):
    id: Union[UUID, int, str]
    name: str


user_03_uuid = UUID('cf57432e-809e-4353-adbd-9d5c0d733868')
user_03 = User(id=user_03_uuid, name='John Doe')
print(user_03)
#> id=UUID('cf57432e-809e-4353-adbd-9d5c0d733868') name='John Doe'
print(user_03.id)
#> cf57432e-809e-4353-adbd-9d5c0d733868
print(user_03_uuid.int)
#> 275603287559914445491632874575877060712

2.限制复合型

  • Literal:需要python3.8
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):
    # discriminator定义限制字段
    pet: Union[Cat, Dog, Lizard] = Field(..., discriminator='pet_type')
    n: int


print(Model(pet={'pet_type': 'dog', 'barks': 3.14}, n=1))
try:
    Model(pet={'pet_type': 'dog'}, n=1)
except ValidationError as e:
    print(e)
    """
    1 validation error for Model
    pet -> Dog -> barks
      field required (type=value_error.missing)
    """

3.嵌套限制复合型

from typing import Literal, Union

from typing_extensions import Annotated

from pydantic import BaseModel, Field, ValidationError


class BlackCat(BaseModel):
    pet_type: Literal['cat']
    color: Literal['black']
    black_name: str


class WhiteCat(BaseModel):
    pet_type: Literal['cat']
    color: Literal['white']
    white_name: str


# Can also be written with a custom root type
#
# class Cat(BaseModel):
#   __root__: Annotated[Union[BlackCat, WhiteCat], Field(discriminator='color')]

Cat = Annotated[Union[BlackCat, WhiteCat], Field(discriminator='color')]


class Dog(BaseModel):
    pet_type: Literal['dog']
    name: str


Pet = Annotated[Union[Cat, Dog], Field(discriminator='pet_type')]


class Model(BaseModel):
    pet: Pet
    n: int


m = Model(pet={'pet_type': 'cat', 'color': 'black', 'black_name': 'felix'}, n=1)
print(m)
#> pet=BlackCat(pet_type='cat', color='black', black_name='felix') n=1
try:
    Model(pet={'pet_type': 'cat', 'color': 'red'}, n='1')
except ValidationError as e:
    print(e)
    """
    1 validation error for Model
    pet -> Union[BlackCat, WhiteCat]
      No match for discriminator 'color' and value 'red' (allowed values:
    'black', 'white')
    (type=value_error.discriminated_union.invalid_discriminator;
    discriminator_key=color; discriminator_value=red; allowed_values='black',
    'white')
    """
try:
    Model(pet={'pet_type': 'cat', 'color': 'black'}, n='1')
except ValidationError as e:
    print(e)
    """
    1 validation error for Model
    pet -> Union[BlackCat, WhiteCat] -> BlackCat -> black_name
      field required (type=value_error.missing)
    """

4.枚举和选择

from enum import Enum, IntEnum

from pydantic import BaseModel, ValidationError


class FruitEnum(str, Enum):
    pear = 'pear'
    banana = 'banana'


class ToolEnum(IntEnum):
    spanner = 1
    wrench = 2


class CookingModel(BaseModel):
    fruit: FruitEnum = FruitEnum.pear
    tool: ToolEnum = ToolEnum.spanner


print(CookingModel(tool=2, fruit='banana'))
try:
    CookingModel(fruit='other')
except ValidationError as e:
    print(str(e))
    """
    1 validation error for CookingModel
    fruit
      value is not a valid enumeration member; permitted: 'pear', 'banana' (type=type_error.enum; enum_values=[<FruitEnum.pear: 'pear'>, <FruitEnum.banana: 'banana'>])
    """

5.日期时间类型

  • datetime:支持datetime对象、strint时间戳
    from datetime import datetime
    # from tzlocal import get_localzone
    from pydantic import BaseModel
    
    
    class Model(BaseModel):
        dt: datetime = None
    
    
    dt = datetime.now()
    # dt = datetime.now(tz=get_localzone())
    
    # 将datetime转为str
    str_dt = dt.strftime('%Y-%m-%d %H:%M:%S.%f')
    
    # 将str转为datetime
    # dt2 = datetime.strptime(str_dt, '%Y-%m-%d %H:%M:%S.%f')
    
    # 将datetime转为时间戳
    dt_stamp = datetime.timestamp(dt)
    
    # 将时间戳转换为datetime
    # dt3 = datetime.fromtimestamp(dt_stamp, get_localzone())
    
    
    # m = Model(dt=dt)
    # m = Model(dt=str_dt)
    m = Model(dt=dt_stamp)
    print(m.json())
    
  • date:支持date和datetime对象、strint时间戳
    from datetime import datetime, date
    from pydantic import BaseModel
    
    
    class Model(BaseModel):
        d: date = None
    
    
    d = datetime.now()
    
    # 将datetime转为str
    str_d = dt.strftime('%Y-%m-%d')
    
    # 将datetime转为时间戳
    d_stamp = datetime.timestamp(dt)
    
    m = Model(d=d)
    # m = Model(d=d.date())
    # m = Model(d=str_d)
    # m = Model(d=d_stamp)
    print(m.json())
    
  • time:支持time对象、str
    from datetime import datetime, time
    from pydantic import BaseModel
    
    
    class Model(BaseModel):
        t: time = None
    
    
    t = datetime.now().time()
    
    # 将datetime转为str
    str_t = datetime.now().strftime('%H:%M:%S.%f')
    
    m = Model(t=t)
    # m = Model(t=str_t)
    print(m.json())
    
  • timedelta:支持timedelta对象、strint
    from datetime import timedelta
    from pydantic import BaseModel
    
    
    class Model(BaseModel):
        td: timedelta = None
    
    
    # timedelta
    td = timedelta(days=1, hours=3, minutes=10)
    
    # str 
    # [-][DD ][HH:MM]SS[.ffffff] | [±]P[DD]DT[HH]H[MM]M[SS]S
    # str_td = "P3DT12H30M5S"
    # str_td = "3 29:18:39"
    str_td = "1 10:48:27.112324"
    
    # int
    int_td = 36000
    
    # m = Model(td=td)
    m = Model(td=str_td)
    # m = Model(td=int_td)
    print(m.dict())
    

6.布尔值

  • 布尔值TrueFalse
  • 整形:0、1
  • 字符串'0', 'off', 'f', 'false', 'n', 'no''1', 'on', 't', 'true', 'y', 'yes'
  • 如果想要严格约束布尔值只能接收FalseTrue,请使用StrictBool
from pydantic import BaseModel


class BooleanModel(BaseModel):
    bool_value: bool


print(BooleanModel(bool_value='no'))

7.文本类型

  • 这是python标准库从python 3.8开始的新功能
  • 此字段类型的一个优点是,它可用于检查与一个或多个特定值的相等性,而无需声明自定义验证程序,可以代替枚举类型
# from typing_extensions import Literal  python < 3.8 时使用
from typing import Literal
from pydantic import BaseModel, ValidationError


class Pie(BaseModel):
    flavor: Literal['apple', 'pumpkin']


Pie(flavor='apple')
Pie(flavor='pumpkin')
try:
    Pie(flavor='cherry')
except ValidationError as e:
    print(str(e))
    """
    1 validation error for Pie
    flavor
      unexpected value; permitted: 'apple', 'pumpkin'
    (type=value_error.const; given=cherry; permitted=('apple', 'pumpkin'))
    """

8.TypedDict类型

  • 这是 python 标准库自 python 3.8 起的新功能。在python 3.8之前,它需要打字扩展包。但是,自python 3.9以来,必填字段和可选字段才得到正确区分。因此,我们建议在python 3.8中使用打字扩展
from typing_extensions import TypedDict

from pydantic import BaseModel, Extra, ValidationError


# `total=False` 标识这两个字段非必要
class UserIdentity(TypedDict, total=False):
    name: str
    surname: str


class User(TypedDict):
    identity: UserIdentity
    age: int


class Model(BaseModel):
    u: User

    class Config:
        # 禁止传递额外字段
        extra = Extra.forbid


# print(Model(u={'identity': {'name': 'Smith', 'surname': 'John'}, 'age': '37'}))
# u={'identity': {'name': 'Smith', 'surname': 'John'}, 'age': 37}

# print(Model(u={'identity': {'name': None, 'surname': 'John'}, 'age': '37'}))
# u={'identity': {'name': None, 'surname': 'John'}, 'age': 37}

# print(Model(u={'identity': {}, 'age': '37'}))
# u={'identity': {}, 'age': 37}


try:
    # 类型错误
    Model(u={'identity': {'name': ['Smith'], 'surname': 'John'}, 'age': '24'})
except ValidationError as e:
    print(e)
    """
    1 validation error for Model
    u -> identity -> name
      str type expected (type=type_error.str)
    """

try:
    # 多余的字段email
    Model(
        u={
            'identity': {'name': 'Smith', 'surname': 'John'},
            'age': '37',
            'email': 'john.smith@me.com',
        }
    )
except ValidationError as e:
    print(e)
    """
    1 validation error for Model
    u -> email
      extra fields not permitted (type=value_error.extra)
    """

9.Pydantic Types

  • FilePath:like ,但路径必须存在并且是文件Path
  • DirectoryPath:like ,但路径必须存在并且是一个目录Path
  • PastDate:like ,但日期应该是过去的date
  • FutureDate:like,,但日期应该在将来date
  • EmailStr:需要安装电子邮件验证器;输入字符串必须是有效的电子邮件地址,输出是简单字符串
  • NameEmail:需要安装电子邮件验证器;输入字符串必须是有效的电子邮件地址或格式,并且输出是具有两个属性的对象:NameEmail(name='dupuffer', email='dupuffer@outlook.com')
  • PyObject:需要一个字符串并加载可在该虚线路径上导入的python对象;例如,如果提供了,则生成的字段值将是函数'math.cos'cos
    from pydantic import BaseModel, PyObject
    
    
    class Model(BaseModel):
        e: PyObject
    
    
    m = Model(e="builtins.ord")
    print(m.e('a'))
    
  • Color:用于解析HTML和CSS颜色;请参阅颜色类型
  • Json:一个特殊的类型包装器,在解析之前加载JSON
  • PaymentCardNumber:用于解析和验证支付卡
  • AnyUrl:任何网址
  • AnyHttpUrl:一个 HTTP 网址
  • HttpUrl:更严格的HTTP网址
    from pydantic import BaseModel, HttpUrl, PostgresDsn, ValidationError, validator
    
    
    class MyModel(BaseModel):
        url: HttpUrl
    
    
    m = MyModel(url='http://www.example.com')
    
    # the repr() method for a url will display all properties of the url
    print(repr(m.url))
    # HttpUrl('http://www.example.com', scheme='http', host='www.example.com',
    # tld='com', host_type='domain', port='80')
    print(m.url.scheme)
    # http
    print(m.url.host)
    # www.example.com
    print(m.url.host_type)
    # domain
    print(m.url.port)
    
  • FileUrl:文件路径网址
  • PostgresDsn:一个postgres DSN样式的URL
  • RabbitMqDsn:RabbitMQ,StormMQ,ActiveMQ等使用的DSN样式URL
  • RedisDsn:RedisDsn
  • stricturl:任意URL约束的类型方法
  • UUID1:需要类型 1 的有效 UUID
  • UUID3:需要类型 3 的有效 UUID
  • UUID4:需要类型 4 的有效 UUID
  • UUID5:需要类型 5 的有效 UUID
  • SecretBytes:字节,其中值保持部分机密
  • SecretStr:值部分保密的字符串
  • IPvAnyAddress:允许IPv4AddressIPv6Address
  • IPvAnyInterface:允许IPv4InterfaceIPv6Interface
  • IPvAnyNetwork:允许IPv4NetworkIPv6Network
  • NegativeFloat:允许负的浮点数;使用标准解析,然后检查值是否小于0;请参见约束类型float
  • NegativeInt:允许一个负的整数;使用标准解析,然后检查值是否小于0;请参见约束类型int
  • PositiveFloat:允许正的浮点数;使用标准解析,然后检查值是否大于0;请参见约束类型float
  • PositiveInt:允许正整数;使用标准解析,然后检查值是否大于0;请参见约束类型int
  • conbytes:用于约束字节的类型方法
  • condecimal:用于约束小数的文字方法
  • confloat:用于约束浮点数的类型方法
  • conint:用于约束 ints 的类型方法
  • conlist:用于约束列表的类型方法
  • conset:用于约束集合的类型方法
  • confrozenset:用于约束冻结集的类型方法
  • constr:用于约束 strs 的类型方法

10.颜色类型

  • 名称:例如,"Black"、"azure"
  • 十六进制值:例如,"0x000"、"#FFFFFF"、"7fffd4"
  • RGB/RGBA 元组:例如,(255, 255, 255)、(255, 255, 255, 0.5)
  • RGB/RGBA 字符串:例如,"rgb(255, 255, 255)"、"rgba(255, 255, 255, 0.5)"
  • HSL 字符串:例如,"hsl(270, 60%, 70%)"、"hsl(270, 60%, 70%, .5)"
from pydantic import BaseModel, ValidationError
from pydantic.color import Color

c = Color('ff00ff')
print(c.as_named())
#> magenta
print(c.as_hex())
#> #f0f
c2 = Color('green')
print(c2.as_rgb_tuple())
#> (0, 128, 0)
print(c2.original())
#> green
print(repr(Color('hsl(180, 100%, 50%)')))
#> Color('cyan', rgb=(0, 255, 255))


class Model(BaseModel):
    color: Color


print(Model(color='purple'))
#> color=Color('purple', rgb=(128, 0, 128))
try:
    Model(color='hello')
except ValidationError as e:
    print(e)
    """
    1 validation error for Model
    color
      value is not a valid color: string not recognised as a valid color
    (type=value_error.color; reason=string not recognised as a valid color)
    """

11.密钥类型

  • 可以使用 和 数据类型来存储不希望在日志记录或回溯中可见的敏感信息。 并且可以完全初始化,也可以分别使用 或 文本 进行初始化。和 将被格式化为或转换为 json 时
from pydantic import BaseModel, SecretStr, SecretBytes


class SimpleModel(BaseModel):
    password: SecretStr
    password_bytes: SecretBytes


sm = SimpleModel(password='IAmSensitive', password_bytes=b'IAmSensitiveBytes')

print(sm.password)  # **********
print(sm.password_bytes)  # **********
print(sm.json())
# {"password": "**********", "password_bytes": "**********"}

# 获取真实数据
print(sm.password.get_secret_value())  # IAmSensitive
print(sm.password_bytes.get_secret_value())  # b'IAmSensitiveBytes'


# If you want the secret to be dumped as plain-text using the json method,
# you can use json_encoders in the Config class.
class SimpleModelDumpable(BaseModel):
    password: SecretStr
    password_bytes: SecretBytes

    class Config:
        # 在调用json方法时会对值进行解析
        json_encoders = {
            SecretStr: lambda v: v.get_secret_value() if v else None,
            SecretBytes: lambda v: v.get_secret_value() if v else None,
        }


sm2 = SimpleModelDumpable(password='IAmSensitive', password_bytes=b'IAmSensitiveBytes')

print(sm2.password)  # **********
print(sm2.dict())
"""
{
    'password': SecretStr('**********'),
    'password_bytes': SecretBytes(b'**********'),
}
"""
#
# But the json method will
print(sm2.json())
"""
{
    "password": "IAmSensitive", 
    "password_bytes": "IAmSensitiveBytes"
}
"""

12.Json类型

  • 自动将json串转为对象
from typing import List

from pydantic import BaseModel, Json, ValidationError


class SimpleJsonModel(BaseModel):
    json_obj: Json


class ComplexJsonModel(BaseModel):
    json_obj: Json[List[int]]


# obj = SimpleJsonModel(json_obj='{"b": 1}')
# print(type(obj.json_obj))  # dict
# print(obj.json_obj)  # {'b': 1}


# obj2 = ComplexJsonModel(json_obj='[1, 2, 3]')
# print(type(obj2.json_obj))  # list
# print(obj2.json_obj)  # [1, 2, 3]


try:
    ComplexJsonModel(json_obj='["a", "b"]')
except ValidationError as e:
    print(e)
    """
    2 validation errors for ComplexJsonModel
    json_obj -> 0
      value is not a valid integer (type=type_error.integer)
    json_obj -> 1
      value is not a valid integer (type=type_error.integer)
    """

13.字节大小

  • 使用数据类型将字节字符串表示形式转换为原始字节,并打印出人类可读的字节版本
from pydantic import BaseModel, ByteSize


class MyModel(BaseModel):
    size: ByteSize


print(MyModel(size=52000).size)
# 52000
print(MyModel(size='3000 KiB').size)
# 3000 * 1024 = 3072000

m = MyModel(size='50 PB')  # 1PB = 1000TB  1PiB = 1024TiB
print(m.size / 1024 / 1024 / 1024 / 1024 / 1024)  # 44.40892098500626

# 将bytes格式化
print(m.size.human_readable())
# 44.4PiB

print(m.size.human_readable(decimal=True))
# 50.0PB

print(m.size / 1024 / 1024 / 1024 / 1024)  # 45474.73508864641
print(m.size.to('TiB'))  # # 45474.73508864641

标签:print,字段,BaseModel,类型,import,Model,type,class,pydantic
来源: https://www.cnblogs.com/puffer/p/16379335.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有