Python用|实现联合类型注解时报str与type不支持|操作数错误
问题原因
|作为联合类型简写是Python 3.10官方正式支持的语法,遇到的报错和语法本身无关,是注解求值时机和写法问题:
默认情况下Python在定义函数/方法时会立即求值参数注解的表达式。之前用Union["Vector", float]不报错,是因为Union是可调用对象,原生支持接收字符串形式的前向引用作为参数;但"Vector" | float是中缀运算表达式,会被当场执行运算:左侧是普通字符串实例,右侧是float类型对象,字符串类型没有实现针对类型对象的|运算逻辑,因此抛出如下错误:
TypeError: unsupported operand type(s) for |: 'str' and 'type'
正确实现方式
可任选以下两种符合官方规范的写法:
- 写法1(推荐):导入
__future__模块的annotations特性,开启注解延迟求值
该特性从Python 3.7开始支持,开启后所有注解不会在定义阶段立即求值,会以字符串形式存储,既可以解决前向引用问题,也不需要给未定义完成的类名额外加引号,写法最简洁:from __future__ import annotations class Vector: def __mul__(self, other: Vector | float): pass - 写法2:将整个联合类型表达式包裹为完整字符串
如果不想开启延迟注解,不要只给前向引用的类名单独加引号,需要把整个联合表达式作为字符串注解,主流类型检查工具(mypy、pyright等)都可以正常识别该语法,运行时也不会触发|运算报错:class Vector: def __mul__(self, other: "Vector | float"): pass
注意事项
不要使用"Vector" | float这类混合字符串字面量和类型对象的|运算写法,只要没开启注解延迟求值,该写法在运行时必然触发上述TypeError。
内容的提问来源于stack exchange,提问作者rencedm112
相关产品推荐
相关产品推荐

