这个答案似乎不适用于泛型。mymyy抱怨"错误:缺少泛型类型a的类型参数";检查以下代码时。我已经尝试使用'A[T]'
的TypeVar,但然后mymyy说"错误:类型变量T是未绑定的。"我还尝试使用AnyA[T]
作为get
的返回类型,但这会产生两个错误消息,已经知道的"错误":缺少泛型类型a的类型参数;和新的错误信息"类型变量AnyA与参数"使用。
如何正确指定get
的返回类型?
import typing
T = typing.TypeVar('T')
AnyA = typing.TypeVar('AnyA', bound='A')
class A(typing.Generic[T]):
def __init__(self, val: T) -> None:
self.val = val
def get(self: AnyA) -> AnyA:
return self
class B(A[T]):
def is_int(self) -> bool:
return isinstance(self.val, int)
if __name__ == '__main__':
b = B(42)
print(b.get().is_int())
我知道这里有三种打字方式:
声明内部自我类型
此方法在mypy
文档中有描述,请参阅可选构造函数的精确类型。
class A(typing.Generic[T]):
_Self = typing.TypeVar('_Self', bound='A[T]')
def __init__(self, val: T) -> None:
self.val = val
def get(self: _Self) -> _Self:
return self
但是,请注意,这是mypy
特定的东西,可能不适用于其他检查器。例如,pyre
还不支持内部自我类型。
使用_typeshed.Self
这节省了声明自定义类型的样板文件,但需要从typeshed导入一些模糊的内容,这将在运行时失败。因此,它必须由typing.TYPE_CHECKING
:
from typing import Any, TYPE_CHECKING
if TYPE_CHECKING:
from _typeshed import Self
else:
Self = Any
class A(typing.Generic[T]):
def __init__(self, val: T) -> None:
self.val = val
def get(self: Self) -> Self:
return self
_typeshed.Self
最初是为了在自定义存根中使用而创建的,但它也适用于内联类型。
Python 3.11及以上版本:typing.Self
最近引入的PEP 673将Self
添加到stdlib中,因此从Python 3.11开始,人们将能够使用它:
from typing import Self
class A(typing.Generic[T]):
def __init__(self, val: T) -> None:
self.val = val
def get(self: Self) -> Self:
return self
目前mypy
还不支持这个功能,但是从1.1.184版本开始pyright
就支持了。