不要再用if else逐个验证用户的输入了

写在前面

现在,我们假设一个场景,程序要获取用户输入的用户信息,其中包括姓名、年龄、邮箱账号。并且保证姓名是字符串,年龄是非负整数,邮箱必须以@example.com结尾。

下面可能是大家最先想到的方式:

# 验证姓名是否为字符串
if not isinstance(name, str):
    print("姓名必须是字符串")
    # 进行相应的处理...

# 验证年龄是否为非负整数
if not age.isdigit() or int(age) < 0:
    print("年龄必须是非负整数")
    # 进行相应的处理...

# 验证邮箱是否以@example.com结尾
if not email.endswith("@example.com"):
    print("邮箱必须以 @example.com 结尾")
    # 进行相应的处理...

# 如果所有字段均验证通过,则进行后续操作
# ...

你可能已经发现了问题,我们这里需要进行判定,当限制条件增加的时候,代码会变的冗长和难以维护。那么有没有一个优雅的方式来解决问题呢?

Pydantic

pydantic 是一个用于数据验证和解析的 Python 库。它提供了强类型检查、数据转换和验证的功能,使得处理数据更加简单、可靠和易于维护。

那么我们来看看 pydantic 如何解决上一节提到的用户信息验证问题。

  1. 定义模型:

使用 pydantic,您可以定义一个模型类,用于描述要验证和解析的数据结构。模型类继承自 pydantic.BaseModel

示例:

from pydantic import BaseModel

class User(BaseModel):
    name: str
    age: int
    email: str
  1. 实例化模型:

您可以使用模型类来实例化一个对象,并传入要验证的数据。pydantic 会自动根据定义的模型进行验证和数据转换。

示例:

user_data = {
    'name''John Doe',
    'age'25,
    'email''john.doe@example.com'
}

user = User(**user_data)
  1. 访问验证后的数据:

通过模型对象的属性,您可以访问经过验证和转换后的数据。

示例:

print(user.name)   # 输出:John Doe
print(user.age)    # 输出:25
print(user.email)  # 输出:john.doe@example.com
  1. 验证数据:

您可以使用模型类的 validate() 方法手动验证数据,而不创建模型对象。这对于仅需验证数据而不需要实例化对象的情况很有用。

示例:

user_data = {
    'name''John Doe',
    'age'25,
    'email''john.doe@example.com'
}

User.validate(user_data)  # 验证数据,如果数据无效将引发异常
  1. 自定义验证规则:

您可以在模型类中定义方法来进行自定义验证。这些方法的命名需要以 validate_<field_name> 的形式,并接受一个参数来表示当前字段的值。

示例:

from pydantic import BaseModel, field_validator


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

   @field_validator('age')
   def validate_age(cls, age):
       if age < 0:
           raise ValueError('年龄不能为负数')
       return age

   @field_validator('email')
   def validate_email(cls, email):
       if not email.endswith('@example.com'):
           raise ValueError('邮箱必须以 @example.com 结尾')
       return email

验证数据

完成自定义验证规则后,当你再次在代码中给uer实例传入非法数据的时候提示错误。

  1. 传入合法数据
# 实例化 User 对象并触发验证
user = User(name='John Doe', age=25, email='johndoe@example.com')
print(user)

结果:

不要再用if else逐个验证用户的输入了

2.传入非法数据

这里我们故意将年龄改为负数,邮箱的后缀改外google.com。这将会引发验证错误。

user2 = User(name='John Doe', age=-25, email='johndoe@google.com')
print(user2)

结果:

不要再用if else逐个验证用户的输入了

pydantic 的其他功能

  1. 声明式验证:pydantic 使用声明式的方式定义验证规则。通过在模型类中声明字段的类型、限制和验证逻辑,可以清晰地描述数据的预期结构和约束条件。

  2. 自动类型转换:pydantic 在验证过程中会自动进行数据类型转换。例如,如果定义的字段类型为整数,但传入的数据是字符串形式的数字,pydantic 会自动将其转换为整数类型。这样简化了数据转换的操作。

  3. 内置验证选项:pydantic 提供了丰富的内置验证选项,如最小值、最大值、正则表达式匹配、字符串长度限制等。您可以直接在字段定义中指定这些选项,而不需要编写复杂的验证逻辑。

  4. 自动错误消息生成:pydantic 会自动生成有意义的错误消息,以指示验证失败的具体原因。这样可以减少手动编写错误消息的工作量,并提供更好的错误提示和调试能力。

  5. 数据解析能力:pydantic 不仅仅是一个验证库,还具备数据解析的能力。它可以将输入数据解析为模型对象,自动验证和转换数据。这样使数据的验证和解析过程更加一体化和统一化。

  6. JSON兼容性:pydantic 对JSON数据具有良好的兼容性。它可以自动将JSON数据转换为模型对象,并将模型对象转换为JSON数据。

  7. 可嵌套模型:pydantic 支持定义嵌套模型,可以处理复杂的数据结构。通过嵌套模型的方式,可以构建具有层级关系的数据结构,并进行相应的验证和解析。

更多信息您可以查阅 pydantic 的官方文档以获得更多详细信息和示例:https://pydantic-docs.helpmanual.io/


原文始发于微信公众号(harvey的网络日志):不要再用if else逐个验证用户的输入了

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/236944.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!