通过langchain-chatchat来学习 - python的pydantic库


前言

今天来看下下面代码画红框的三个地方。先看第16行,这块很简单,就是规范下包引入的范围。
all 是 Python 中的一个特殊变量,用于定义模块、类或包的公共接口。它在执行通配符导入(例如 from module import *)时只有 ApiModelWorker、ApiChatParams、ApiCompletionParams 和 ApiEmbeddingsParams 将被导入。未列在 all 中的任何内容都不会被导入。
这对于控制模块或包的公共接口非常有用。它可以通过只暴露必要的对象来防止命名空间污染。
下面的BaseModel,实际上是 pydantic库。今天我们来学习下这个库。
在这里插入图片描述


一、pydantic库是做什么的?

pydantic是一个Python库,用于数据验证和解析。它提供了一个简单而强大的方式来定义数据模型,然后可以使用这些模型来验证和解析数据。

它的主要功能包括:

  1. 声明式模型定义:使用类来定义数据模型,通过在类的属性上添加注解来指定数据类型和验证规则。

  2. 数据验证:可以对输入的数据进行验证,例如验证数据类型、长度、范围等。

  3. 数据解析:可以将输入的数据解析为定义好的模型对象,自动转换数据类型并应用指定的验证规则。

  4. 自动文档生成:可以根据模型定义自动生成API文档,包括数据类型、验证规则等信息。

  5. 数据序列化:可以将模型对象序列化为JSON字符串或其他格式,并支持自定义编码器。

总的来说,pydantic提供了一种简单、便捷、安全的方式来定义和处理数据模型,可以提高开发效率并减少错误。

二、通过实例来学习

1. @root_validator装饰器

我们在上面的例子中增加@root_validator(pre=True)装饰器。下面是修改后的代码示例:

from pydantic import BaseModel, root_validator

class User(BaseModel):
    name: str
    age: int

    @root_validator(pre=True)
    def check_age(cls, values):
        age = values.get('age')
        if age < 0:
            raise ValueError('年龄不能是负数')
        return values

user_data = {
    'name': 'Alice',
    'age': -30
}

try:
    user = User(**user_data)
except ValueError as e:
    print(e)

这样,check_age方法将在根校验之前执行,以确保年龄不是负数。
在这里插入图片描述
在 Python 中,** 是一个特殊的语法,用于将一个字典解包为关键字参数。

在上面的代码中,user = User(**user_data) 中的 **user_data 表示将 user_data 字典中的键值对作为关键字参数传递给 User 类的构造函数。

具体来说,User(**user_data) 会将 user_data 字典中的键作为参数名,值作为参数值传递给 User 类的构造函数。

例如,假设 user_data 字典的内容为 {‘name’: ‘John’, ‘age’: 25},那么 User(**user_data) 相当于 User(name=‘John’, age=25)。

这种用法可以使您更灵活地创建 User 实例,因为您可以使用一个字典来存储实例的属性值,并将其传递给构造函数。这在处理动态数据或从其他来源获取数据时非常有用。

请注意,**user_data 只适用于字典类型的参数。如果 user_data 不是一个字典,将会引发一个 TypeError 异常。

2. @validator 装饰器

我们也可以更精细的对每一个字段进行判断,并给出不同错误信息

from pydantic import BaseModel, validator


class User(BaseModel):
    name: str

    @validator('name')
    def validate_name(cls, name):
        if not isinstance(name, str):
            raise ValueError('姓名必须是字符串')
        if len(name) > 10:
            raise ValueError('姓名长度不能超过10个字符')
        return name


if __name__ == '__main__':
    try:
        user = User(name=12345678901)  # 正确,name满足条件
    except ValueError as e:
        print(e)
 

结果可能和大家想的不一样,它不会“报姓名必须是字符串”,因为定义了 name: str 会自动转换,只有转换不了的时候,才会报错。
在这里插入图片描述

3. 自动文档生成

自动生成文档的方法可以用两句话实现
user_schema = User.schema()
print(user_schema)

示例如下

from pydantic import BaseModel, root_validator

class User(BaseModel):
    name: str
    age: int

    @root_validator(pre=True)
    def check_age(cls, values):
        age = values.get('age')
        if age < 0:
            raise ValueError('年龄不能是负数')
        return values

user_data = {
    'name': 'Alice',
    'age': -30
}


if __name__ == '__main__':
    user_schema = User.schema()
    print(user_schema)
    try:
        user = User(**user_data)
    except ValueError as e:
        print(e)
        

运行结果:
在这里插入图片描述


总结

回来看代码是不是就很简单了。唯一要说明的是 代码里 @root_validator(pre=True)和@root_validator(pre=False) 的区别
测试:

from pydantic import BaseModel, root_validator

class User(BaseModel):
    name: str
    age: int

    @root_validator(pre=False)
    def check_name(cls, values):
        name = values.get('name')
        if name is None or name == '':
            raise ValueError('姓名不能为空')
        return values

    @root_validator(pre=False)
    def check_age(cls, values):
        age = values.get('age')
        if age < 0:
            raise ValueError('年龄不能是负数')
        return values

user_data = {
    'name': '',
    'age': -30
}


if __name__ == '__main__':
    user_schema = User.schema()
    print(user_schema)
    try:
        user = User(**user_data)
    except ValueError as e:
        print(e)

看结果
在这里插入图片描述

from pydantic import BaseModel, root_validator

class User(BaseModel):
    name: str
    age: int

    @root_validator(pre=True)
    def check_name(cls, values):
        name = values.get('name')
        if name is None or name == '':
            raise ValueError('姓名不能为空')
        return values

    @root_validator(pre=True)
    def check_age(cls, values):
        age = values.get('age')
        if age < 0:
            raise ValueError('年龄不能是负数')
        return values

user_data = {
    'name': '',
    'age': -30
}


if __name__ == '__main__':
    user_schema = User.schema()
    print(user_schema)
    try:
        user = User(**user_data)
    except ValueError as e:
        print(e)

在这里插入图片描述

  • 31
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值