我一直在尝试了解如何在 Python 中指定类方法的返回类型,以便即使对于子类也能正确解释它(例如在我的 Sphinx 文档中)。
假设我有:
class Parent:
@classmethod
def a_class_method(cls) -> 'Parent':
return cls()
class Child(Parent):
pass
什么如果我希望父级为
a_class_method
,子级为
Parent
,我应该指定为
Child
的返回类型吗?我也尝试过
__qualname__
,但这似乎也不起作用。我应该不注释返回类型吗?
提前致谢!
遇到的问题是正在尝试使用 Python 的类型提示来执行 Python 通常不支持的操作: 运行时类型信息,用于调度行为 。类型提示主要用于静态分析和在运行时很大程度上被忽略。
以下是可以解决此问题的几种方法:
1. 使用 TypeVar 进行泛型行为(推荐)
```python from typing import TypeVar
T = TypeVar('T', bound='Parent')
class Parent: @classmethod def a_class_method(cls: type[T]) -> T: return cls()
class Child(Parent): pass
reveal_type(Parent.a_class_method()) # 显示 "Parent"
reveal_type(Child.a_class_method()) # 显示 "Child"
``
这允许类型检查器理解
a_class_method` 应该返回与其调用它的类相同的类型。
2. 文档,而不是依赖于代码中的精确类型
```python class Parent: @classmethod def a_class_method(cls) -> 'Parent': """返回此类的实例。
Returns:
Parent 的一个实例:此类的实例,可能是子类。
"""
return cls()
class Child(Parent): pass ```
在这种情况下,接受类型提示对于子类不会完全准确,而是在文档中解释该方法的行为。
其他注意事项:
- Python 中的类型提示不是为了在运行时强制执行而设计的。 它们主要用于静态分析工具(如 MyPy)以及提高代码清晰度。
-
__qualname__
用于获取成员的限定名称, 并且不会改变返回类型的行为。
总的来说,使用
TypeVar
是最准确地表示
a_class_method
行为的类型安全方法。但是,请记住,Python 中的类型提示主要用于静态分析,而不是运行时类型检查。