为什么我会在参数化泛型上丢失`__doc__`?

问题描述 投票:0回答:1

问题

在泛型上设置类型参数时,文档字符串会丢失。

最小示例:

from typing import TypeVar, Generic

T = TypeVar("T")

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

assert Test.__doc__ == "My docstring"

这按预期工作得很好。然而,这失败了,因为

__doc__
现在是
None
:

assert Test[int].__doc__ == "My docstring"

期待

我希望文档字符串仍然相同。毕竟还是“同一个”班级。

有什么我不明白的关于 Python 的类型系统如何做出这种有意行为的事情吗?

背景

在 FastAPI 中使用参数化类型,在生成 OpenAPI 规范时我会丢失描述(来自文档字符串)。

我可以使用装饰器解决这个问题,但这会导致我的 Pydantic 模型创建出现更多问题。但这不是重点。我想了解为什么这种情况首先发生,无论非内置工具如何。

python generics python-typing
1个回答
0
投票

用户定义的泛型类型是

typing._BaseGenericAlias
的实例。如果您查看 源代码,这将向您展示它如何将属性从
Test
中继到
Test[int]

    def __getattr__(self, attr):
        ...
        # `__doc__` is a dunder              vvvvvvvvvvvvvvvvvvvv
        if '__origin__' in self.__dict__ and not _is_dunder(attr):
            return getattr(self.__origin__, attr)
        raise AttributeError(attr)

__getattr__
仅在
typing._BaseGenericAlias
实例尚不具有该属性时才激活,因此像
__call__
(允许通过
Test[int]()
进行类实例化)之类的东西仍然可以正常工作,因为
typing._BaseGenericAlias
在显式类而不是中继它们。

© www.soinside.com 2019 - 2024. All rights reserved.