Python 打字,mypy 根据class 方法推断return 类型return 类型
Python typing, mypy infer return type based on class method return type
考虑一下当我有不同的 类 实现相同的方法而 return 使用不同的类型时的情况。
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()
的确切 return 类型,这取决于它的参数 x
。我如何帮助 Mypy 实现这一点?
注意:还请考虑我要与函数do_method()
一起使用的类数量太多,因此不想全部更改。
您可以使用 generic protocol 来完成您需要的操作。但是需要注意的是,mypy要求protocol函数的return类型的协变是TypeVar
,所以我们必须显式声明为covariant=True
,否则变量为默认情况下被视为不变量。
方法的协变 return 类型是当方法在子类中被覆盖时可以被“更窄”类型替换的方法。
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*'
考虑一下当我有不同的 类 实现相同的方法而 return 使用不同的类型时的情况。
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()
的确切 return 类型,这取决于它的参数 x
。我如何帮助 Mypy 实现这一点?
注意:还请考虑我要与函数do_method()
一起使用的类数量太多,因此不想全部更改。
您可以使用 generic protocol 来完成您需要的操作。但是需要注意的是,mypy要求protocol函数的return类型的协变是TypeVar
,所以我们必须显式声明为covariant=True
,否则变量为默认情况下被视为不变量。
方法的协变 return 类型是当方法在子类中被覆盖时可以被“更窄”类型替换的方法。
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*'