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的主要优势:

  1. 验证:自动验证数据类型和约束条件
  2. 转换:智能类型转换(如字符串转数字)
  3. 默认值:支持动态默认值生成
  4. 序列化:轻松转换为字典或JSON
  5. 扩展性:支持自定义验证器和复杂嵌套结构

对于更复杂的模式,可以结合使用@root_validator进行跨字段验证,或者定义嵌套模型。如果不需要数据类的功能,也可以单独使用Pydantic的验证器。

总结:用Pydantic,真省事。


项目地址都忘记贴了=.=: https://github.com/toaco/rubric

回到顶部