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

为何参数化泛型会丢失__doc__属性?

泛型参数化后文档字符串丢失的原因与解决方法

问题本质

当你给泛型类传入类型参数(如Test[int])时,Python会动态生成一个泛型别名类(GenericAlias)——它不是原泛型类的实例,而是一个独立的类对象。这个动态生成的类默认不会继承原类的__doc__属性,这就是文档字符串丢失的核心原因。

你可以通过类型验证直观确认:

print(type(Test))          # <class 'type'>,原类是标准类对象
print(type(Test[int]))     # <class 'typing._GenericAlias'>(Python 3.8)或 <class 'types.GenericAlias'>(Python 3.9+),是动态生成的别名类

这是预期行为吗?

是的,这是Python泛型系统的原生设计。泛型别名主要服务于静态类型检查和类型注解场景,运行时它的属性继承逻辑并不完整,__doc__属于未被自动复制的属性之一。原泛型类和参数化后的别名类在运行时是两个完全不同的对象,因此后者不会自动携带前者的文档字符串。

针对FastAPI/Pydantic场景的解决思路

如果你需要在FastAPI生成OpenAPI规范时保留文档字符串,可以尝试以下方案:

1. 手动复制文档字符串

适合少量使用的场景,直接在参数化后赋值:

TestInt = Test[int]
TestInt.__doc__ = Test.__doc__

2. 自定义泛基类自动保留文档字符串

通过重写__class_getitem__方法,在生成泛型别名时自动复制原类的__doc__:

from typing import TypeVar, Generic

T = TypeVar("T")

class DocGeneric(Generic[T]):
    @classmethod
    def __class_getitem__(cls, item):
        generic_alias = super().__class_getitem__(item)
        generic_alias.__doc__ = cls.__doc__
        return generic_alias

class Test(DocGeneric[T]):
    """My docstring"""

assert Test[int].__doc__ == "My docstring"  # 断言可通过

注意:不同Python版本的泛型别名实现可能有差异,需测试适配你的环境。

3. 利用Pydantic/FastAPI原生配置

如果使用Pydantic的GenericModel,可以通过model_config或字段描述补充文档,避免依赖类的__doc__。例如在FastAPI中直接给路径操作参数指定description,而非依赖类的文档字符串。

内容的提问来源于stack exchange,提问作者ts91

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 15:17:39