如何在Python 3.10中扩展Annotated标注类型?
解决Annotated类型扩展问题
要实现不嵌套注解且合并元数据的效果,你可以手动提取原Annotated类型的底层类型和元数据,再和新的元数据组合成新的Annotated类型。
方法一:手动拆解组合
直接获取Alpha的底层类型和元数据,再添加新约束:
from typing import Annotated, get_args from pydantic import Field, BeforeValidator Alpha = Annotated[str, Field(pattern=r'[A-Za-z]')] # 提取原Annotated的底层类型和元数据 base_type, *base_metadata = get_args(Alpha) # 合并原元数据和新元数据,生成新类型 ShortAlpha = Annotated[base_type, *base_metadata, BeforeValidator(lambda x: len(x) <= 5)]
这样ShortAlpha的元数据会包含原Alpha的Field(pattern=r'[A-Za-z]')和新增的BeforeValidator,不会出现嵌套问题。
方法二:封装工具函数
如果需要多次扩展,可以写个工具函数来自动合并元数据:
from typing import Annotated, get_args, TypeVar T = TypeVar('T') def extend_annotated(annotated_type: Annotated, *new_metadata) -> Annotated: base_type, *base_metadata = get_args(annotated_type) return Annotated[base_type, *base_metadata, *new_metadata] # 使用示例 ShortAlpha = extend_annotated(Alpha, BeforeValidator(lambda x: len(x) <= 5)) Max10Alpha = extend_annotated(Alpha, Field(max_length=10))
这个函数可以重复使用,避免每次手动拆解的繁琐。
验证效果
用Pydantic模型测试一下:
from pydantic import BaseModel class TestModel(BaseModel): short_alpha: ShortAlpha # 合法输入 obj1 = TestModel(short_alpha="abc") print(obj1) # 输出: short_alpha='abc' # 违反长度约束 try: obj2 = TestModel(short_alpha="abcdef") except Exception as e: print(e) # 输出: 1 validation error for TestModel # short_alpha # Invalid input type (type=value_error) # 违反字符约束 try: obj3 = TestModel(short_alpha="123") except Exception as e: print(e) # 输出: 1 validation error for TestModel # short_alpha # String should match pattern '[A-Za-z]' (type=value_error.str.regex; pattern=[A-Za-z])
可以看到两个约束都生效了,说明元数据合并成功。
内容的提问来源于stack exchange,提问作者snakecharmerb
相关产品推荐
相关产品推荐

