Python打字,mypy根据类方法返回类型推断返回类型

时间:2021-01-04 06:17:10

标签: python mypy python-typing

考虑当我有不同的类实现相同的方法同时返回不同的类型时的情况。

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() 一起使用的此类类的数量太多,因此不想全部更改。

1 个答案:

答案 0 :(得分:3)

您可以使用 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*'