简体   繁体   English

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

[英]Python typing, mypy infer return type based on class method return type

Consider the case when I have different classes implementing the same method while returning different types.考虑当我有不同的类实现相同的方法同时返回不同的类型时的情况。

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 is not being able to infer the exact return type of function do_method() which depends on its argument x . Mypy 无法推断 function do_method()的确切返回类型,这取决于其参数x How can I help Mypy achieve this?我如何帮助 Mypy 实现这一目标?

Note: Please also consider that number of such classes that I want to use with the function do_method() is too many, so one doesn't want to change them all.注意:还请考虑我想与 function do_method()一起使用的此类数量太多,因此不想全部更改。

You could use generic protocol to do what you need.您可以使用通用协议来做您需要的事情。 But it should be minded that mypy requires the covariance of the return type of the function of protocol when it is a TypeVar , so we must explicitly state this by covariant=True , otherwise the variable is considered as an invariant by default.但需要注意的是,mypy 需要协议的 function 的返回类型为TypeVar时的协方差,所以我们必须通过covariant=True显式地 state ,否则默认情况下该变量被视为不变量。

A covariant return type of a method is one that can be replaced by a "narrower" type when the method is overridden in a subclass.方法的协变返回类型是在子类中重写该方法时可以用“更窄”类型替换的类型。

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*'

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM