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