Python child 类 的输入问题

Python typing issue for child classes

这个问题是为了澄清我对python打字

的疑惑
from typing import Union

class ParentClass:
    parent_prop = 1

class ChildA(ParentClass):
    child_a_prop = 2

class ChildB(ParentClass):
    child_b_prop = 3

def method_body(val) -> ParentClass:
    if val:
        return ChildA()
    else:
        return ChildB()

def another_method() -> ChildA:
    return method_body(True)

print(another_method().child_a_prop)

上面这段代码中,我使用的linting工具打印错误如下

error: Incompatible return value type (got "ParentClass", expected "ChildA")

(我在哪里method_body(真)

我也将 method_body return 类型设置为 Union[ChildA, ChildB]。 这将导致 error: Incompatible return value type (got "Union[ChildA, ChildB]", expected "ChildA")

我正在寻找更好的方法来做到这一点。 如果有人知道解决方案,将不胜感激。

mypy 不进行运行时分析,所以它无法猜测调用 method_body 与参数 True 将始终导致 ChildA 对象。所以它产生的错误确实有道理。

您必须以某种方式引导 mypy 告诉他您知道自己在做什么,并且 another_method 在使用参数 True 调用时确实会生成一个 ChildA 对象。一种是使用 cast:

from typing import cast
def another_method() -> ChildA:
    return cast(ChildA, method_body(True))

还有一个是加断言:

def another_method() -> ChildA:
    result = method_body(True)
    assert isinstance(result, ChildA)
    return result

两者之间的区别在于 cast 没有任何运行时含义。您可以将其视为放在这里指导 mypy 检查的注释,但 cast 函数仅 returns 它的第二个参数,即,这里是 cast 的主体:

def cast(typ, val):
    return val

assert 自然会引发 AssertionError 错误(显然不是那种情况,但通常如此)。

自然 ParentClassChildA 不兼容,因为并非所有 ParentClass 实例都是 ChildAUnion[ChildA, ChildB].

也是如此

为了 another_method 通过类型检查,我们需要向类型检查器提供有关所涉及的运行时类型的附加信息,即 method_boy(True) 将始终 return ChildA,不只是一个ParentClass。这可以使用 typing.cast:

来完成
def another_method() -> ChildA:
    return typing.cast(ChildA, method_body(True))