在泛型上设置类型参数时,文档字符串会丢失。
最小示例:
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 模型创建出现更多问题。但这不是重点。我想了解为什么这种情况首先发生,无论非内置工具如何。
用户定义的泛型类型是
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
在显式类而不是中继它们。