5分钟掌握Pydantic

devtools/2024/9/22 15:48:53/

数据模型定义:使用 Python 类来定义数据模型,这些类可以自动将输入转换为 Python 数据类型。

python">from pydantic import BaseModelclass User(BaseModel):id: intname: stremail: str

类型检查:Pydantic 强制执行类型检查,确保传入的数据符合模型定义的类型。

python">user = User(id=1, name='John Doe', email='john.doe@example.com')
# 如果传递错误的类型,比如将id作为字符串,将会引发错误

自动转换:Pydantic 可以将字符串输入自动转换为 Python 原生类型,如 int, float, bool, datetime 等。

python">class User(BaseModel):id: int = Field(..., alias='user_id')  # 使用别名email: struser = User(user_id='123', email='john.doe@example.com')
print(user.id)  # 输出: 123

错误处理:当输入数据不符合模型定义时,Pydantic 提供了详细的错误信息,方便调试。

python">try:User(id='invalid', name='John Doe', email='john.doe@example.com')
except ValidationError as e:print(e.json())

配置选项:Pydantic 允许通过配置选项来自定义模型的行为,如是否允许额外字段,是否进行严格的类型检查等。

python">from pydantic import BaseModel, Extra, Field# 定义一个模型
class User(BaseModel):id: intname: stremail: str# 内部类 Config 用于设置配置选项class Config:# 指定如何处理模型中未定义的额外字段extra = Extra.allow  # 允许额外字段,它们将被存储在模型的 additional 字典中# 指定是否允许修改模型实例的属性allow_mutation = False  # 不允许修改,使模型实例成为不可变的# 指定是否将 JSON 字段名作为属性名,而不是 Python 变量名alias_generator = lambda x: x  # 使用字段的 JSON 名称作为属性名# 指定是否将带下划线的属性视为私有underscore_attrs_are_private = True  # 将带下划线的属性视为私有# 指定是否在模型初始化时进行严格的类型检查strict_types = True  # 开启严格类型检查# 指定是否允许使用任意类型作为字段类型arbitrary_types_allowed = False  # 不允许任意类型# 指定是否将枚举的值用作 JSON 序列化use_enum_values = True  # 使用枚举值而不是枚举的名称# 指定 JSON 编码器json_encoders = {int: lambda x: str(x)  # 为整数定义自定义 JSON 编码器}# 为 JSON Schema 指定额外的字段json_schema_extra = {'example': {'id': 1, 'name': 'Alice', 'email': 'alice@example.com'}  # 示例数据}

泛型模型:支持泛型模型,可以创建基于泛型的复杂数据结构。

python">from typing import List, Dictclass ModelGenerics(BaseModel):data: List[str]config: Dict[str, str]data = ModelGenerics(data=['item1', 'item2'], config={'key': 'value'})

在 Python 3.5 中引入,作为对泛型的支持。

在 Python 的 typing 模块中,Optional 和 Union 是两个非常有用的类型注解工具,它们经常一起使用来表达某些类型上的需求。

Optional

Optional 是一个用于表示某个类型的值可能存在,也可能是 None 的类型注解。它通常用于函数注解中,来表明一个参数可以被省略(默认为 None),或者一个变量可能有值或没有值。

Union

Union 是一个类型注解工具,它允许一个变量可以是多种类型中的一种。它使用圆括号 () 来包裹多个类型,表示变量可以是这些类型中的任何一个。

Optional[Union[int, str]]

当你看到 Optional[Union[int, str]] 这样的类型注解时,它的意思是:

  • 这个注解表示的变量可以接受以下三种情况之一:
    1. 一个整数 (int)
    2. 一个字符串 (str)
    3. 没有值,即 None

在函数注解中,这通常表示一个参数可以是整数、字符串或者完全不传(默认为 None)。
下面是一个使用 Optional[Union[int, str]] 的例子:

python">from typing import Optional, Uniondef process_value(value: Optional[Union[int, str]]) -> str:if value is None:return "No value provided"elif isinstance(value, int):return f"The value is an integer: {value}"elif isinstance(value, str):return f"The value is a string: {value}"else:return "Unknown type"

Callable
在 Python 中,Callable 是 typing 模块提供的一个泛型类型,用于注解函数对象。当你想要定义一个变量、参数或者返回值必须是一个函数时,可以使用 Callable。
Callable 的使用格式如下:

Callable[[arg1_type, arg2_type, ..., argN_type], return_type]
  • arg1_type, arg2_type, …, argN_type 是函数参数的类型。
  • return_type 是函数返回值的类型。

JSON 支持:Pydantic 可以轻松地将模型序列化为 JSON,也可以从 JSON 反序列化模型。

序列化为 JSON

python">user = User(id=1, name='John Doe', email='john.doe@example.com')
user_json = user.json()  # 序列化为JSON字符串
print(user_json)

JSON 反序列化模型

python">'{"id": 1,"name": "John Doe","email": "john.doe@example.com"
}'user_json = '''
{"id": 1,"name": "John Doe","email": "john.doe@example.com"
}
'''user = User.parse_raw(user_json)
print(user)
print(user.id, user.name, user.email)

环境变量加载:Pydantic 可以自动从环境变量中加载配置。

python">from pydantic import BaseSettings# 定义一个继承自 BaseSettings 的 Settings 类
class Settings(BaseSettings):# 定义一个名为 DEBUG 的布尔类型配置项,并设置默认值为 FalseDEBUG: bool = False# 定义一个名为 DB_USER 的字符串类型配置项,没有默认值,需要从环境变量或其它方式提供DB_USER: str# 定义一个名为 DB_PASSWORD 的字符串类型配置项,同样需要外部提供DB_PASSWORD: str# 创建 Settings 类的实例
settings = Settings()# 打印 DEBUG 配置项的值,由于没有指定环境变量或其它赋值方式,将输出默认值 False
print(settings.DEBUG)# 尝试打印 DB_USER 配置项的值
# 如果没有通过环境变量或其它方式提供 DB_USER 的值,这将抛出一个错误,因为没有默认值
print(settings.DB_USER)

字段校验:提供了多种字段校验器,用于验证数据的有效性,如长度、正则表达式匹配等。

python">from pydantic import BaseModel, Field, validator
from typing import Listclass User(BaseModel):name: stremail: strpasswords: List[str] = Field(..., min_items=2)@validator('email')def email_must_contain_at(cls, v):if '@' not in v:raise ValueError('must contain @')return vuser = User(name='John', email='john.doe', passwords=['pass1', 'pass2'])

pydantic 与JSON Schema 关系与关系

JSON Schema 是一种基于 JSON 格式的声明性语言,用于描述和验证 JSON 数据结构。它最初由 JSON 的创建者 Douglas Crockford 提出概念,并由一个社区驱动的进程进一步开发和标准化。JSON Schema 的目的是为了让 JSON 数据能够自我描述,即包含足够的元数据来描述其自身的结构,从而允许自动化的验证和编辑。

JSON Schema 的主要用途包括:

  1. 数据验证:确保 JSON 数据符合预定义的模式,比如检查数据类型、格式、长度等。
  2. 自动化测试:自动化测试工具可以使用 JSON Schema 来验证 API 返回的数据是否符合预期。
  3. API 文档:作为 API 文档的一部分,帮助开发者理解 API 请求和响应的数据结构。
  4. 配置管理:用于定义配置文件的结构,确保配置文件中的设置是有效和合理的。
  5. 用户界面生成:基于 JSON Schema 自动生成表单和用户界面,以输入和编辑数据。
  6. 数据交换:作为不同系统或组件之间交换数据时的契约,确保数据的兼容性。

JSON Schema 被广泛应用于各种编程语言和环境中,是现代软件开发中数据验证和描述的重要工具之一。随着 JSON 格式的普及,JSON Schema 也成为了描述 JSON 数据的事实标准之一。

要将 Pydantic 模型转换为 JSON Schema,你可以使用模型的 schema() 方法。下面是一个示例:

python">from pydantic import BaseModel, Fieldclass User(BaseModel):id: intname: stremail: str# 定义一个字段的额外信息,比如示例值email = Field(..., example='user@example.com')# 获取 JSON Schema 表示
schema = User.schema()print(schema)

运行上述代码会输出类似于下面的 JSON Schema:

{"$schema": "http://json-schema.org/draft-07/schema#","title": "User","type": "object","properties": {"id": {"type": "integer"},"name": {"type": "string"},"email": {"type": "string","format": "email"}},"required": ["id","name","email"],"example": {"id": 0,"name": "","email": "user@example.com"}
}

请注意,输出的 JSON Schema 包含了模型的所有字段,它们的类型,以及是否是必须的。此外,如果字段使用了 Field 函数来定义额外的元数据(如示例值),这些信息也会被包含在内。

JSON Schema 可以用于各种用途,包括:

  • 自动化测试:验证输入数据是否符合预期的模型。
  • API 文档:为 API 提供正式的、可机器读取的文档。
  • 代码生成:基于 JSON Schema 自动生成代码,如客户端库或服务端存根。
  • 交互式表单:基于 JSON Schema 自动生成表单界面。

Pydantic 的 schema() 方法是一个非常强大的工具,可以帮助你将 Python 模型定义转换为一个广泛接受的、标准化的格式。

Pydantic 支持嵌套模型,这意味着你可以在一个 Pydantic 模型中定义另一个 Pydantic 模型作为其字段之一。这使得你可以创建复杂的数据结构,如对象包含对象,或者对象包含数组等。

嵌套模型示例

假设我们有一个博客系统,需要定义 PostUser 两个模型,其中 Post 模型嵌套了 User 模型:

python">from pydantic import BaseModelclass User(BaseModel):name: stremail: strclass Post(BaseModel):title: strcontent: strauthor: User  # 这里 Post 嵌套了 User 模型作为其字段published: bool = False# 创建 Post 实例
post = Post(title='Pydantic 嵌套模型',content='Pydantic 是多么方便啊!',author=User(name='Alice', email='alice@example.com'),published=True
)print(post)

在这个例子中:

  • User 是一个包含 nameemail 字段的 Pydantic 模型。
  • Post 是另一个 Pydantic 模型,它有一个 author 字段,该字段的类型是 User。这样,Post 模型就嵌套了 User 模型。
  • 创建 Post 实例时,你需要为 author 字段提供一个 User 实例。

嵌套模型的 JSON Schema

当你为嵌套的 Pydantic 模型生成 JSON Schema 时,Pydantic 会自动处理这些嵌套关系,生成相应的 schema:

python">print(Post.schema())

这将输出一个包含 PostUser 模型的 JSON Schema,其中 Postauthor 字段会链接到 User 的 schema。

嵌套模型的序列化和反序列化

Pydantic 同样支持嵌套模型的序列化(将模型实例转换为 JSON)和反序列化(从 JSON 创建模型实例):

python"># 序列化 Post 实例为 JSON
post_json = post.json()
print(post_json)# 假设有一段 JSON 字符串表示 Post
post_json_str = '''
{"title": "Pydantic 嵌套模型","content": "Pydantic 是多么方便啊!","author": {"name": "Alice","email": "alice@example.com"},"published": true
}
'''# 反序列化 JSON 字符串为 Post 实例
post_from_json = Post.parse_raw(post_json_str)
print(post_from_json)

通过嵌套模型,Pydantic 提供了一种强大的方式来处理复杂的数据结构,同时保持了序列化和反序列化的便利性。


http://www.ppmy.cn/devtools/31075.html

相关文章

HTML中input输入框(详解输入框的用法)

目录 一、input介绍 1.概念 2.好处 3.用法 4.应用 二、input语法 1.文本输入框 (type"text") 2.密码输入框 (type"password") 3.数字输入框 (type"number") 4.电子邮件输入框 (type"email") 5.复选框 (type"checkbox&…

GO语言核心30讲 进阶技术 (第一部分)

原站地址:Go语言核心36讲_Golang_Go语言-极客时间 一、数组和切片 1. 两者最大的不同:数组的长度是固定的,而切片的长度是可变的。 2. 可以把切片看成是对数组的一层封装,因为每个切片的底层数据结构中,一定会包含一…

数据结构与算法之经典排序算法

一、简单排序 在我们的程序中,排序是非常常见的一种需求,提供一些数据元素,把这些数据元素按照一定的规则进行排序。比如查询一些订单按照订单的日期进行排序,再比如查询一些商品,按照商品的价格进行排序等等。所以&a…

常用设计模式

单例模式 一个类只能创建一个对象,即单例模式,该设计模式可以保证系统中该类只有⼀个实例,并提供⼀个访问它的全局访问点,该实例被所有程序模块共享。比如在某个服务器程序中,该服务器的配置信息存放在⼀个文件中&…

高可用系列四:loadbalancer 负载均衡

负载均衡可以单独使用,也常常与注册中心结合起来使用,其需要解决的问题是流量分发,这是就需要定义分发策略,当然也包括了故障切换的能力。 故障切换 故障切换是负载均衡的基本能力,和注册中心结合时比较简单&#xf…

Arduino 推出带 Wi-Fi的 32 位 UNO 板

Arduino 推出了下一代 UNO 板,引入了 32 位 Renesas 微控制器和 Espressif ESP32-S3 模块、一键云连接和大量 I/O 以及 128 红色 LED 矩阵。新型 UNO R4 板有两个版本,带 Wi-Fi 连接和不带 Wi-Fi 连接,并保持了 UNO R3 的外形尺寸、屏蔽兼容性…

工具链工具——映射与调度、模拟与验证、开发与测试工具

本篇文章将重点介绍工具链的工具相关知识,我们将从工具链的基本概念出发,重点介绍工具链中的映射和调度工具、模拟与验证工具、开发和测试工具,最后提出对工具链发展的展望,从而对工具链的工具进行一个较为系统的讲解。 工具链的…

网络安全之密码学技术

文章目录 网络信息安全的概念数据加密|解密概念密码学概论密码学分类古典密码学现代密码学 现代密码学的相关概念对称加密算法对称加密算法—DES对称加密算法—3DES对称加密算法—AES对称加密算法—IDEA 非对称加密算法非对称加密算法—RSA非对称加密算法—ElGamal非对称加密算…