Python中如何实现基于模式定义的对象验证器/转换器/生成器?
我的想法是主要实现这么一个库:使用 Python 定义模式,然后可以用改模式来:
- 验证一个 Python 对象是否符合该模式
- 将一个对象转换成符合该模式的对象
- 随机生成符合该模式的对象
- 基于该模式,提供一些其他库的扩展,比如:
- flask/django 的参数验证扩展
- pymongo 的简单 orm
PyPI 上面类似的库是有的,但是觉得其 API 不好用,因此打算重新造一个轮子,下面是已经实现了的判断对象是否符合模式的例子:
schema = {
'a': [],
'b': [
{
'c': int,
'd': Int(default=3),
'e': [str]
}
],
'c': Int(validator=lambda x: 1 < x < 10)
}
rubric.validate(schema, {
‘a’: [],
‘b’: [
{
‘c’: 1,
‘d’: 2,
‘e’: [‘hello’, ‘world’]
}
],
‘c’: 7
}) # pass
目前功能都只实现了部分(只作了验证,很多类型的验证规则也还没定义),代码也不到 200 行,因此特意来此找感兴趣的朋友来一起完成这个项目,主要是:
- 一起设计出更好用的 API
- 完成其他未完成的功能
代码注释丰富,测试也很多,除了 pytest 之外不依赖任何第三方库.稍微熟悉 python 就可以了~,感兴趣的朋友快一起来吧~~
Python中如何实现基于模式定义的对象验证器/转换器/生成器?
3 回复
对于在Python中实现基于模式定义的对象验证/转换/生成器,我推荐使用Pydantic库。它通过类型注解来定义数据模型,能自动处理验证、数据转换和序列化。
下面是一个完整示例:
from typing import List, Optional
from pydantic import BaseModel, Field, validator
from datetime import datetime
# 定义数据模型
class User(BaseModel):
id: int
username: str = Field(min_length=3, max_length=20)
email: str
age: Optional[int] = Field(None, ge=0, le=150)
created_at: datetime = Field(default_factory=datetime.now)
tags: List[str] = []
# 自定义验证器
@validator('email')
def validate_email(cls, v):
if '@' not in v:
raise ValueError('Invalid email format')
return v.lower()
# 数据转换示例
@validator('username', pre=True)
def normalize_username(cls, v):
return str(v).strip().lower() if v else v
# 使用示例
if __name__ == "__main__":
# 1. 验证和转换
user_data = {
'id': '123', # 自动转换为int
'username': ' JOHN_DOE ', # 自动去除空格并转小写
'email': 'Test@Example.COM',
'age': '25', # 自动转换为int
'tags': ['python', 'developer']
}
try:
user = User(**user_data)
print(f"验证成功: {user}")
print(f"用户名: {user.username}") # 输出: john_doe
print(f"邮箱: {user.email}") # 输出: test@example.com
# 2. 生成默认值
new_user = User(id=456, username='alice', email='alice@example.com')
print(f"\n创建时间已自动生成: {new_user.created_at}")
# 3. 序列化为字典/JSON
print(f"\n转为字典: {user.dict()}")
print(f"转为JSON: {user.json()}")
except Exception as e:
print(f"验证失败: {e}")
Pydantic的主要优势:
- 验证:自动验证数据类型和约束条件
- 转换:智能类型转换(如字符串转数字)
- 默认值:支持动态默认值生成
- 序列化:轻松转换为字典或JSON
- 扩展性:支持自定义验证器和复杂嵌套结构
对于更复杂的模式,可以结合使用@root_validator进行跨字段验证,或者定义嵌套模型。如果不需要数据类的功能,也可以单独使用Pydantic的验证器。
总结:用Pydantic,真省事。
项目地址都忘记贴了=.=: https://github.com/toaco/rubric

