python-3.x - 对象通过类型函数时的Mypy行为?
问题描述
在以下情况下,我似乎不理解 Mypy 的行为。此问题的代码已简化
import typing as t
...
self._store:t.Dict[str,str] = dict()
...
def set_kv(self, key:str, value:int)->t.Any:
assert isinstance(key, six.string_types)
assert isinstance(value, six.string_types)
with self.__lock.write():
self.__store[key] = value
self.__persist()
我通过运行以下命令使用 mypy 测试此代码
mypy docido_sdk/index/test.py --ignore-missing-imports --follow-imports=error --strict-optional
现在理想情况下,这应该在 line 处引发错误self.__store[key]= value
。但事实并非如此。当我删除assert isinstance(value, six.string_types)
时,它才会抛出错误。isinstance 是下面给出的典型函数
def isinstance(__o: object, __t: Union[type, Tuple[Union[type, Tuple], ...]]) -> bool: ...
这是 mypy 的 bug 还是预期的行为,因为如果我理解正确isinstance
应该不会影响 mypy 对value
.
解决方案
当您调用时,isinstance()
您正在对value
.
在调用isinstance()
mypy 之前认为value
是一个int
但实际上在运行时它可能会有所不同。isinstance()
调用后value
必须是一个str
.
mypy 知道isinstance()
,所以它把它当作一个明确的指令来覆盖它认为它知道的任何东西value
并相应地更新它的模型。
同样,如果您value: Union[int, str]
在检查后if isinstance(value, str): ...
mypy 可以更新其对宇宙的看法并知道value
现在是 astr
而不是int
. 在这种情况下,这似乎更直观。
这里的问题是可能的类型不相交,所以 mypy 只是将类型视为唯一可以是的类型:str
.
顺便说一句,typescript 会更好地处理这种情况,因为它有一个类型never
来处理这种不应该发生的情况,并且当你对never
值进行意外操作时会产生错误。
Mypy 没有这个概念,因此它不善于捕捉此类问题,因为它实际上可能是故意的:类型系统仅提供提示,因此您可能有合理的代码来生成运行时断言来处理类型假设是错误的。
推荐阅读
- python - 访问类型为 Union 的变量的属性会引发错误
- javascript - 在 ReactJS 中,如何在迭代非浅层数据结构时最好地组织我的代码
- javascript - 在新窗口中打开图像出现javascript的空白页面
- laravel-5 - Laravel 和 Vue.js API 文件上传不起作用
- java - Socket java 向服务器传输一个位串。StringBuilder 转移
- android - Android API 28 和 Roboelectric 4.0-alpha-3 抛出 Realm lib 错误
- angularjs - 引导工具提示:如果绑定变量值为空,则隐藏工具提示
- youtube - Youtube API - 来自频道统计的视频数量与上传的视频数量之间的差异
- c++ - 通常使用什么方法来检测时间情况?
- c++ - 如何在派生构造函数中多次构造基类