Python数据验证利器:详解Pydantic的使用方法

如何使用Pydantic进行数据验证:Python开发者必读

文章目录

Pydantic 是目前最广泛使用的 Python 数据验证库之一。它不仅快速且可扩展,还能与各种静态分析工具(如 MyPy、Pyright)和 IDE 良好配合。通过纯正的 Python 3.8+语法定义数据模型,并使用 Pydantic 进行验证。

Pydantic 用法示例

首先,我们来看一个简单的 Pydantic 示例,创建一个继承自BaseModel的自定义类:

from datetime import datetime
from typing import Tuple

from pydantic import BaseModel


class Delivery(BaseModel):
    timestamp: datetime
    dimensions: Tuple[int, int]


m = Delivery(timestamp='2020-01-02T03:04:05Z', dimensions=['10', '20'])
print(repr(m.timestamp))
#> datetime.datetime(2020, 1, 2, 3, 4, 5, tzinfo=TzInfo(UTC))
print(m.dimensions)
#> (10, 20)

上面的代码展示了如何使用 Pydantic 来定义数据模型并进行数据验证。我们定义了一个Delivery类,该类包含timestampdimensions两个字段,Pydantic 会自动将输入的数据转换为合适的类型并进行验证。

为什么使用 Pydantic?

  • 类型提示驱动:Pydantic 充分利用 Python 的类型提示(type hints)来定义和验证数据模型。这意味着你可以在定义数据模型时直接使用 Python 的类型注解,而不需要额外的 Schema 定义。这种方法减少了代码重复,提高了可读性。
  • 集成 IDE 和静态分析工具:由于 Pydantic 基于类型提示,它与 IDE 和静态分析工具(如 MyPy、Pyright)无缝集成。开发者可以在编写代码时获得即时反馈和自动完成提示,从而提高开发效率。
  • 性能:Pydantic 的核心验证逻辑是用 Rust 编写的,因此在性能上有显著优势。对于需要处理大量数据的应用程序来说,Pydantic 提供了更快的数据验证。
  • 内置的 JSON Schema 生成:虽然 Pydantic 本身不是基于 JSON Schema 的,但它可以从 Pydantic 模型生成 JSON Schema。这使得它可以轻松地与需要 JSON Schema 的工具和框架集成,提供了最佳的兼容性。
  • 更少的学习成本:使用 Pydantic,你只需了解 Python 的类型提示和基本的 Pydantic 语法,而不需要学习 JSON Schema 的语法。这对于已经熟悉 Python 的开发者来说,学习成本更低。
  • 严格和宽松模式:Pydantic 可以在strict=True模式(数据不被转换)和strict=False模式(Pydantic 尝试将数据转换为正确类型)之间切换。
  • 数据类和类型字典:Pydantic 支持许多标准库类型的验证,包括dataclassTypedDict
  • 灵活性和扩展性:Pydantic 允许开发者定义自定义验证器和序列化器,提供了极大的灵活性和扩展性。这意味着你可以根据自己的需求精确控制数据验证和处理的方式。
  • 生态系统:Pydantic 有一个庞大且活跃的社区,许多流行的 Python 库(如 FastAPI、Django Ninja、SQLModel)都依赖 Pydantic 进行数据验证和序列化。这意味着在实际应用中,你可以找到许多使用 Pydantic 的优秀示例和最佳实践。

安装 Pydantic 非常简单:

pip install pydantic

Pydantic 更多示例

让我们来看另一个例子,创建一个自定义类并进行数据验证:

from datetime import datetime

from pydantic import BaseModel, PositiveInt


class User(BaseModel):
    id: int
    name: str = 'John Doe'
    signup_ts: datetime | None
    tastes: dict[str, PositiveInt]


external_data = {
    'id': 123,
    'signup_ts': '2019-06-01 12:22',
    'tastes': {
        'wine': 9,
        b'cheese': 7,
        'cabbage': '1',
    },
}

user = User(**external_data)

print(user.id)
#> 123
print(user.model_dump())
"""
{
    'id': 123,
    'name': 'John Doe',
    'signup_ts': datetime.datetime(2019, 6, 1, 12, 22),
    'tastes': {'wine': 9, 'cheese': 7, 'cabbage': 1},
}
"""

在这个例子中,我们定义了一个User类,并使用 Pydantic 进行数据验证和转换。

  1. idint 类型;Pydantic 会将字符串、字节或浮点数转换为整数,否则会引发异常。
  2. name 是字符串类型;因为有默认值,所以不是必需的。
  3. signup_tsdatetime 类型的字段,可以为 None
  4. tastes 是一个键为字符串,值为正整数的字典。

如果验证失败,Pydantic 会引发一个包含错误详细信息的异常:

from pydantic import ValidationError


class User(BaseModel):
    id: int
    name: str = 'John Doe'
    signup_ts: datetime | None
    tastes: dict[str, PositiveInt]


external_data = {'id': 'not an int', 'tastes': {}}

try:
    User(**external_data)
except ValidationError as e:
    print(e.errors())
    """
    [
        {
            'type': 'int_parsing',
            'loc': ('id',),
            'msg': 'Input should be a valid integer, unable to parse string as an integer',
            'input': 'not an int',
            'url': 'https://errors.pydantic.dev/2/v/int_parsing',
        },
        {
            'type': 'missing',
            'loc': ('signup_ts',),
            'msg': 'Field required',
            'input': {'id': 'not an int', 'tastes': {}},
            'url': 'https://errors.pydantic.dev/2/v/missing',
        },
    ]
    """

以上代码演示了在输入数据无效时,Pydantic 如何提供详细的错误信息。

总结

Pydantic 是一个功能强大且灵活的 Python 数据验证库,它利用类型注解来简化代码编写,并通过高效的 Rust 核心实现了卓越的性能。无论是数据验证、类型转换还是与其他工具的集成,Pydantic 都提供了全面且易用的解决方案。

要了解更多关于 Pydantic 的信息和示例,可以访问Pydantic 的官方文档


也可以看看