You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过编程创建带类型注解的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 08:59:17