Python 为子类的实例键入签名?
Python typing signature for instance of subclass?
考虑:
from __future__ import annotations
class A:
@classmethod
def get(cls) -> A:
return cls()
class B(A):
pass
def func() -> B: # Line 12
return B.get()
运行 mypy 我们得到:
$ mypy test.py
test.py:12: error: Incompatible return value type (got "A", expected "B")
Found 1 error in 1 file (checked 1 source file)
此外,我检查了旧式递归注释是否有效。即:
# from __future__ import annotations
class A:
@classmethod
def get(cls) -> "A":
# ...
...无济于事。
当然可以:
from typing import cast
def func() -> B: # Line 12
return cast(B, B.get())
每次都会弹出这个案例。但我想避免这样做。
应该如何输入?
cls
和self
参数通常由mpyp
推断,以避免大量冗余代码,但需要时可以通过注解显式指定。
在这种情况下,class 方法的显式类型如下所示:
class A:
@classmethod
def get(cls: Type[A]) -> A:
return cls()
所以我们在这里真正需要的是一种使 Type[A]
成为通用参数的方法,这样当 class 方法被子 class 调用时,您可以引用child class 代替。幸运的是,我们有 TypeVar
个值。
将其应用到您现有的示例中,我们将得到以下内容:
from __future__ import annotations
from typing import TypeVar, Type
T = TypeVar('T')
class A:
@classmethod
def get(cls: Type[T]) -> T:
return cls()
class B(A):
pass
def func() -> B:
return B.get()
现在 mypy
应该又是你的朋友了!
考虑:
from __future__ import annotations
class A:
@classmethod
def get(cls) -> A:
return cls()
class B(A):
pass
def func() -> B: # Line 12
return B.get()
运行 mypy 我们得到:
$ mypy test.py
test.py:12: error: Incompatible return value type (got "A", expected "B")
Found 1 error in 1 file (checked 1 source file)
此外,我检查了旧式递归注释是否有效。即:
# from __future__ import annotations
class A:
@classmethod
def get(cls) -> "A":
# ...
...无济于事。
当然可以:
from typing import cast
def func() -> B: # Line 12
return cast(B, B.get())
每次都会弹出这个案例。但我想避免这样做。
应该如何输入?
cls
和self
参数通常由mpyp
推断,以避免大量冗余代码,但需要时可以通过注解显式指定。
在这种情况下,class 方法的显式类型如下所示:
class A:
@classmethod
def get(cls: Type[A]) -> A:
return cls()
所以我们在这里真正需要的是一种使 Type[A]
成为通用参数的方法,这样当 class 方法被子 class 调用时,您可以引用child class 代替。幸运的是,我们有 TypeVar
个值。
将其应用到您现有的示例中,我们将得到以下内容:
from __future__ import annotations
from typing import TypeVar, Type
T = TypeVar('T')
class A:
@classmethod
def get(cls: Type[T]) -> T:
return cls()
class B(A):
pass
def func() -> B:
return B.get()
现在 mypy
应该又是你的朋友了!