在许多现代 Python 应用程序中,尤其是在处理传入数据(例如,来自 API 的 JSON 有效负载)的应用程序中,确保数据的有效性、完整性和正确类型至关重要。Pydantic 是一个强大的库,允许您使用标准的 Python 类型提示为您的数据定义模型,然后自动根据这些模型验证任何传入数据。在本例中,我们将展示如何建模一个典型的用例:用户为产品下订单。我们将使用 Pydantic 定义 User、Product 和 Order 模型,确保电子邮件、价格、数量和用户详细信息等数据符合我们指定的约束。

步骤 1:安装依赖

pip install pydantic
pip install pydantic[email]

使用 pip install pydantic 安装核心库,启用使用 Python 类型提示进行数据验证。 另外,运行 pip install pydantic[email] 以获得内置的电子邮件验证功能。

步骤 2:定义 Pydantic 模型 (User、Product 和 Order)

from typing import List, Optional
from pydantic import BaseModel, Field, EmailStr, conint, ValidationError


# 定义模型
class User(BaseModel):
    name: str = Field(..., min_length=1, max_length=50, description="用户的全名")
    email: EmailStr = Field(..., description="用户电子邮件地址,由 Pydantic 验证")
    age: Optional[conint(ge=0, le=120)] = Field(None, description="可选年龄,具有实际范围")
    phone_number: Optional[str] = Field(None, pattern=r'^\+?[1-9]\d{1,14}$', description="可选电话号码,E.164 格式")


class Product(BaseModel):
    name: str = Field(..., min_length=1, max_length=100)
    price: float = Field(..., gt=0, description="价格必须大于零")
    quantity: conint(gt=0) = Field(..., description="数量必须大于零")


class Order(BaseModel):
    order_id: int = Field(..., gt=0, description="订单 ID 必须为正整数")
    user: User
    products: List[Product] = Field(..., description="订单中的产品列表")


    # 计算属性
    @property
    def total_cost(self) -> float:
        return sum(product.price * product.quantity for product in self.products)

通过以上代码,这三个 Pydantic 模型 User、Product 和 Order 提供了一种结构化、经过验证的方法来管理应用程序数据。User 模型对姓名、电子邮件、可选年龄和与模式匹配的可选电话号码强制执行约束。Product 模型确保有效的名称长度、正价格和非零数量。最后,Order 模型将用户和产品联系在一起,同时计算订单的总成本。

步骤 3:在 main() 函数中实现验证

def main():
    # 有效用户字典示例
    user_data = {
        "name": "Jane Doe",
        "email": "jane.doe@example.com",
        "age": 30,
        "phone_number": "+1234567890"
    }


    # 产品数据示例
    products_data = [
        {"name": "Keyboard", "price": 49.99, "quantity": 1},
        {"name": "Mouse", "price": 19.99, "quantity": 2}
    ]


    # 将用户和产品组合成订单
    order_data = {
        "order_id": 101,
        "user": user_data,
        "products": products_data
    }


    try:
        # 实例化模型以触发验证
        valid_user = User(**user_data)
        print("User Model:", valid_user)


        valid_products = [Product(**pd) for pd in products_data]
        print("Product Models:", valid_products)


        valid_order = Order(**order_data)
        print("Order Model:", valid_order)
        print(f"订单总成本: {valid_order.total_cost}")


    except ValidationError as e:
        print("验证错误:", e)

现在,这个 main() 函数模拟接收用户和多个产品的数据,然后创建并验证相应的 User、Product 和 Order 实例。它演示了如果任何数据未能通过验证,Pydantic 如何引发 ValidationError,否则打印出经过验证的模型和计算出的总成本。

步骤 4:执行程序

# 运行 main() 函数
main()

我们调用 main() 来执行演示,该演示验证我们的示例用户、产品和订单数据。运行该函数后,它将打印出经过验证的模型,如果数据未能通过验证,则打印出任何错误。

输出

User Model: name='Jane Doe' email='jane.doe@example.com' age=30 phone_number='+1234567890' Product Models: [Product(name='Keyboard', price=49.99, quantity=1), Product(name='Mouse', price=19.99, quantity=2)] Order Model: order_id=101 user=User(name='Jane Doe', email='jane.doe@example.com', age=30, phone_number='+1234567890') products=[Product(name='Keyboard', price=49.99, quantity=1), Product(name='Mouse', price=19.99, quantity=2)] 订单总成本: 89.97

代码的输出将如上所示。

在此示例中,我们演示了 Pydantic 如何在真实世界的工作流程中为 User、Product 和 Order 定义和验证数据模型。Pydantic 通过指定字段类型、约束和自定义验证来确保输入到这些模型中的任何数据都是正确的。这有助于您尽早捕获错误,简化代码逻辑,并提高数据密集型应用程序的可靠性。