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

Sob*_*iev 3 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'
Run Code Online (Sandbox Code Playgroud)

Mypy 无法推断函数的确切返回类型do_method(),这取决于其参数x。我如何帮助 Mypy 实现这一目标?

注意:还请考虑到我想与该函数一起使用的此类类的数量do_method()太多,因此不想将它们全部更改。

ale*_*ame 5

您可以使用通用协议来完成您需要的操作。但需要注意的是,当 protocol 函数的返回类型为 a 时,mypy 要求其返回类型具有协变性,TypeVar因此我们必须通过 显式声明这一点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*'
Run Code Online (Sandbox Code Playgroud)