【问题标题】:Python typing, mypy infer return type based on class method return typePython打字,mypy根据类方法返回类型推断返回类型
【发布时间】:2021-01-04 06:17:10
【问题描述】:
考虑当我有不同的类实现相同的方法但返回不同的类型时的情况。
class A:
def method(self) -> float:
return 3.14
class B:
def method(self) -> str:
return 'a string'
def do_method(x):
return x.method()
r = do_method(A())
reveal_type(r) # Revealed type is 'Any'
Mypy 无法推断函数 do_method() 的确切返回类型,这取决于其参数 x。我如何帮助 Mypy 实现这一目标?
注意:还请考虑我想与函数do_method() 一起使用的此类数量太多,因此不想全部更改。
【问题讨论】:
标签:
python
mypy
python-typing
【解决方案1】:
您可以使用generic protocol 来做您需要的事情。但需要注意的是,mypy在为TypeVar时需要protocol的函数返回类型的协方差,所以我们必须通过covariant=True明确说明这一点,否则默认认为该变量是不变量。
方法的协变返回类型是在子类中重写该方法时可以被“更窄”类型替换的类型。
from typing import TypeVar, Protocol
T = TypeVar('T', covariant=True)
class Proto(Protocol[T]):
def method(self) -> T: ...
class A:
def method(self) -> float:
return 3.14
class B:
def method(self) -> str:
return 'a string'
def do_method(x: Proto[T]) -> T:
return x.method()
r1 = do_method(A())
reveal_type(r1) # Revealed type is 'builtins.float*'
r2 = do_method(B())
reveal_type(r2) # Revealed type is 'builtins.str*'