web*_*elo 7 python mypy python-typing
考虑:
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()
Run Code Online (Sandbox Code Playgroud)
运行 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)
Run Code Online (Sandbox Code Playgroud)
此外,我还检查了旧式递归注释是否有效。那是:
$ 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)
Run Code Online (Sandbox Code Playgroud)
...没有用。
当然可以这样做:
# from __future__ import annotations
class A:
@classmethod
def get(cls) -> "A":
# ...
Run Code Online (Sandbox Code Playgroud)
每次都会出现这样的情况。但我想避免这样做。
应该如何输入此内容?
和参数通常通过推断来避免大量冗余代码,但在需要时可以通过注释显式指定它们cls。selfmpyp
在这种情况下,类方法的显式类型如下所示:
class A:
@classmethod
def get(cls: Type[A]) -> A:
return cls()
Run Code Online (Sandbox Code Playgroud)
所以我们这里真正需要的是一种制作Type[A]泛型参数的方法,这样当从子类调用类方法时,就可以引用子类了。幸运的是,我们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()
Run Code Online (Sandbox Code Playgroud)
现在mypy应该又是你的朋友了!
| 归档时间: |
|
| 查看次数: |
955 次 |
| 最近记录: |