如何通过编程创建带类型注解的Python类?解决type方法注解缺失问题
编程创建带类型注解的BaseModel子类与类装饰器实现
一、直接用type创建带类型注解的类
手动定义class Foo(BaseModel): bar: str = "baz"时,Python会自动将类型注解收集到类的__annotations__字典中。用type创建类时,需要显式传入__annotations__字典,才能让BaseModel的元类识别到类型信息:
from pydantic import BaseModel # 正确创建带类型注解的Foo类 Foo = type( "Foo", (BaseModel,), { "__annotations__": {"bar": str}, "bar": "baz" } ) # 验证注解是否存在 print(Foo.__annotations__) # 输出: {'bar': <class 'str'>} # 验证BaseModel的校验逻辑生效 print(Foo(bar="test")) # 输出: Foo(bar='test')
二、实现类装饰器:克隆类并修改类型注解
要创建带有修改后注解的类克隆,且让注解在类创建时就被元类识别,可以通过装饰器内部调用type重新构建类来实现:
from pydantic import BaseModel def modify_annotations(new_annotations): def decorator(cls): # 合并原注解与新注解(新注解会覆盖同名原注解) updated_annotations = {**cls.__annotations__, **new_annotations} # 收集原类的可继承属性,保留必要的特殊属性 class_attrs = {} for attr_name, attr_value in cls.__dict__.items(): # 保留非特殊属性,或指定的特殊属性(如模块名、类名、注解) if not attr_name.startswith('__') or attr_name in ('__annotations__', '__module__', '__qualname__', '__doc__'): class_attrs[attr_name] = attr_value # 更新注解字典 class_attrs['__annotations__'] = updated_annotations # 克隆类,继承原类的父类 cloned_class = type( f"Cloned{cls.__name__}", cls.__bases__, class_attrs ) return cloned_class return decorator # 使用示例 class OriginalFoo(BaseModel): bar: str = "baz" num: int = 10 # 克隆并修改注解:将bar的类型改为int,新增desc字段的注解 @modify_annotations({"bar": int, "desc": str}) class ModifiedFoo(OriginalFoo): # 可以在这里添加新的默认值,或留空 desc = "default description" # 验证效果 print(ModifiedFoo.__annotations__) # 输出: {'bar': <class 'int'>, 'num': <class 'int'>, 'desc': <class 'str'>} print(ModifiedFoo(bar=200, num=300)) # 输出: ModifiedFoo(bar=200, num=300, desc='default description')
关键说明
- 装饰器通过
type重新构建类,确保新类的__annotations__在创建阶段就被设置,BaseModel的元类能正常读取并应用校验规则。 - 合并注解时使用字典解包,新注解会覆盖原类中同名的注解;如果需要新增注解,直接在
new_annotations中添加即可。 - 收集原类属性时过滤了大部分特殊属性,仅保留必要的(如
__module__保证类的模块归属正确),避免不必要的属性干扰。
内容的提问来源于stack exchange,提问作者Nat
相关产品推荐
相关产品推荐

