pydantic - 更方便地编写 entity 类
什么是pydantic
Pydantic 是一个 Python 库,专门用于数据验证和配置管理,它使用 Python 类型注解来定义数据结构。你可以把它看作是一种方式,确保你的应用程序接收到的数据符合预期的格式和类型。
Pydantic 的核心思想是:你创建一个 Python 类,其中每个属性都带有类型注解(例如 int, str, list[int])。Pydantic 会根据这些注解自动生成验证逻辑。当你创建一个类的实例时,Pydantic 会检查传入的数据是否符合定义的类型和约束。如果不符合,它会抛出一个 ValidationError,告诉你哪些地方出了问题。
简单来讲, pydantic 帮助我们更方便和规范地编写entity类
python 原生编写entity类的例子
我们写一个User类的例子:
import src.configs.config
from loguru import loggerclass User1:def __init__(self, id: int, name:str ="No Name", email:str|None = None, friends:list[int]=[]):self.id = idself.name = name self.email = emailself.friends = friends# getter
@property
def email(self):return self._email# setter
@email.setter
def email(self, value):if "@" not in value:raise ValueError("Email must contain an '@' symbol.")self._email = valueif __name__ == "__main__":alice = User1(1, "Alice","alice.he@5mi.com")logger.info(alice.__dict__)try:bob = User1( 3, "Bob","bobafk.com",[]) # didn' triggerred validationexcept ValueError as e:logger.info("ValueError occurred")logger.error(e)
可以看出若干不方便的地方:
- 参数的类型和名字分开编写 , 不太直观
- 额外地编写getter 和setter
- 属性校验写在setter 中, 未能被构造函数触发
使用pydantic 的例子:
import src.configs.config
from loguru import logger
from pydantic import BaseModel, field_validatorclass User2(BaseModel):id: intname: str = "No name"email: str | None= Nonefriends: list[int]=[]@field_validator("email")@classmethoddef validate_email(cls, email: str):logger.info(f"Validating email: {email}")if "@" not in email:raise ValueError("Email must contain an '@' symbol.")return emailif __name__ == "__main__":# must be with attribute name, and it don't need to define the constructor __init__()user = User2(id=1, name="Mike", email="mike@usa.com", friends=[])user.name="Jay" # we don't need the setter and getter!logger.info(f"user name: {user.name}")try:danny = User2(id=2,name="Danny",email="dannyeu.com",friends=[])except ValueError as e:logger.info("ValueError occurred")logger.error(e)
优点很明显:
- 属性的定义和类型写在一起, 可读性更高
- 不需要手动写getter和setter, 但该类仍有setter和getter的功能。
- 属性校验有专门的方法, 更加规范,能被构造函数触发