Python类型注解:如何断言联合类型中的具体类型?
解决静态类型检查器无法识别类型窄化的问题
问题根源是静态类型检查器(比如mypy)没法通过type(ans) == float这种判断完成类型窄化,换用isinstance、类型断言或者typing.cast都能解决,不用依赖# type: ignore。下面是具体方案:
方案1:用isinstance做类型判断
静态类型检查器对isinstance的类型推导支持更完善,替换原有的type()判断后,检查器能自动识别剩下的ans是int类型:
def f1(*args, **kwargs) -> int | float: ... def f2(*args, **kwargs) -> int: ans = f1(*args, **kwargs) if isinstance(ans, float): return -1 return ans # 检查器现在能正确识别这里的ans是int
方案2:用类型断言(Python 3.10+)
如果一定要用type()判断,可以用类型断言明确告诉检查器当前ans的类型:
def f1(*args, **kwargs) -> int | float: ... def f2(*args, **kwargs) -> int: ans = f1(*args, **kwargs) if type(ans) == float: return -1 return ans as int # Python 3.10+支持的类型断言语法
方案3:用typing.cast(兼容低版本Python)
对于Python 3.10以下的版本,用typing.cast来强制指定变量类型:
from typing import cast def f1(*args, **kwargs) -> int | float: ... def f2(*args, **kwargs) -> int: ans = f1(*args, **kwargs) if type(ans) == float: return -1 return cast(int, ans)
补充说明
type()判断之所以不被检查器认可,是因为它只匹配精确类型,没法覆盖float子类的情况(虽然实际开发中几乎不会这么用),而isinstance会考虑继承关系,所以检查器更信任isinstance的类型窄化逻辑,优先推荐用方案1。
内容的提问来源于stack exchange,提问作者Dario
相关产品推荐
相关产品推荐

