子类的 Python 输入问题

标签 python mypy python-typing

这个问题是为了澄清我对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(True))

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

我正在寻找一种更好的方法来做到这一点。 如果有人知道解决方案,我们将非常感谢您的帮助。

最佳答案

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

你必须以某种方式引导 mypy 告诉他你知道你在做什么,并且 another_method 在使用参数 调用时确实会产生一个 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 函数只返回它的第二个参数,即这里是 cast 的主体:

def cast(typ, val):
    return val

assert 可以自然地引发​​ AssertionError 错误(在这种情况下显然不是,但一般情况下)。

关于子类的 Python 输入问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70015750/

相关文章:

python - Google Colab 在多大程度上支持 Python 类型?

python - 到处使用 `from __future__ import annotations` 有什么缺点吗?

python - 获取用户内存消耗的脚本或命令

python - 删除数据框侧括号中的内容

python - Mypy 为带有 attrs 包的装饰类的子类返回错误 "Unexpected keyword argument"

python-3.x - 当参数可以具有从特定基类型派生的任何类型时,如何注释抽象方法的参数类型?

python - 如何在 Python 中创建用户定义类型断言?

Python 多处理(joblib)参数传递的最佳方式

python - 使用opencv和python将图像转换为值(例如十六进制代码)

python - 为什么 mypy 推断公共(public)基类型而不是所有包含类型的联合?