mypy 在评估算术计算的类型时未考虑先前执行的类型检查
Posted
技术标签:
【中文标题】mypy 在评估算术计算的类型时未考虑先前执行的类型检查【英文标题】:mypy not taking previously performed typecheck into account when evaluating types for arithmetic computation 【发布时间】:2022-01-03 17:06:40 【问题描述】:我有一个如下所示的 python 类:
from typing import Optional, Union, Dict
import numpy as np
class TestClass():
def __init__(self, a: Optional[float] = None, b: Optional[float] = None):
self.a = 1 if a is None else a
self.b = b
@property
def input_values(self) -> Dict[str, Union[float, None]]:
return 'a': self.a, 'b': self.b
@property
def test_property(self) -> float:
if None in self.input_values.values():
raise KeyError('missing values')
return self.a+self.b
用 mypy 评估它会返回错误语句
error: Unsupported operand types for + ("float" and "None")
note: Right operand is of type "Optional[float]"
但我要确保在控制流的这一点上这两个值都不能为 None。 mypy 是否可以通过不同的方式来执行这些类型检查?
【问题讨论】:
你必须看到mypy没有做运行时分析。所以它不会从测试if None in self.input_values.values()
中学到任何东西,因为它需要实际执行方法input_values
。对于 mypy,在您的 return 语句中,self.b
的类型为 Optional[float]
(因为它在 __init__
方法中进行了初始化)。就是这样。
@qouify 但如果我将稍后用于算术的值的输入类型设置为 Optional[float] mypy 会引发错误。我还能保留此功能并继续使用 mypy 吗?
如果您真的需要 b
成为 Optional[float]
而不是像您对 a
所做的那样强制它成为 float
,您可以随时使用 cast
确保b
肯定不能包含None
,就像这样:typing.cast(float, self.b)
。 mypy 可以在其类型检查中利用此信息。
(顺便说一句,你或许应该删除你以前的帖子,这似乎是这篇文章的草稿。)
你有什么理由去构建一个辅助dict
进行检查吗?一个简单的if self.b is None:
就足够了。
【参考方案1】:
mypy 中类型的缩小非常有限,允许的方法之一是 assert,这在 mypy 中有效:
def test_property(self) -> float:
if None in self.input_values.values():
raise KeyError('missing values')
assert isinstance(self.a, float) and isinstance(self.b, float)
return self.a + self.b
【讨论】:
以上是关于mypy 在评估算术计算的类型时未考虑先前执行的类型检查的主要内容,如果未能解决你的问题,请参考以下文章
评估 numpy.radians 和浮点/数组输入元素的类型提示