为何mypy中issubclass类型收窄仅对type实例生效?是否为bug?
为什么单独使用
issubclass无法让mypy完成类型收窄? 这不是mypy的bug,属于预期行为,原因如下:
issubclass运行时要求第一个参数必须是类对象(也就是type的实例),如果传入普通实例、基本类型这类非类对象,会直接抛出TypeError。- 当变量类型是
Any时,mypy无法提前确定它是不是合法的类对象。单独写issubclass(o, MyClass)时,mypy没法排除o是非法参数的可能,自然不敢贸然收窄类型——毕竟这行代码在运行时可能直接报错,mypy不会假设代码在这种场景下是安全的。 - 而先通过
isinstance(o, type)确认o是类对象后,mypy能确定issubclass的调用是合法的,这时结合issubclass(o, MyClass)的检查,就能安全地把类型收窄为Type[MyClass]。
结合你的代码示例来看:
from typing import Any class MyClass: pass def f(o: Any) -> None: if isinstance(o, type) and issubclass(o, MyClass): reveal_type(o) # Revealed type is "Type[MyClass]" if issubclass(o, MyClass): reveal_type(o) # Revealed type is "Any"
第一个分支里的前置类型检查给了mypy足够的信息,让它能完成类型收窄;第二个分支没有这个前提,mypy只能保持原有的Any类型。
内容的提问来源于stack exchange,提问作者Leonardus Chen
相关产品推荐
相关产品推荐

