myunionA
可以是整数或整数列表。如何编写类型提示以反映这一点?
它尝试了以下代码,并使用mypy对其进行了测试。最后一行失败-请参阅错误文本。
numbers: List[int]
myunionA: Union[int, List[int]]
myunionB: Union[int, List[int]]
numbers = [11, 22]
numbers[2] = 3
myunionA = 2
myunionB[2] = 22 # ERROR(mypy): Unsupported target for indexed assignment
如何编写类型提示让我分配整数或整数列表?
正如deceze在评论中所说,您的代码确实不正确。如果有人要执行以下操作怎么办?
# Legal, since myunionB can be *either* int or List[int]
myunionB: Union[int, List[int]] = 99
# Boom! At runtime, we get a "int is not subscriptable" error
myunionB[2] = 22
如果您希望mypy了解您的并集当前正好是一个列表,则需要缩小执行isinstance检查或类似操作的变量的类型。
if isinstance(myunionB, list):
# Type of myunionB is understood to be just List[int] here,
# so this type-checks
myunionB[2] = 22
else:
# And myunionB is understood to be just int here
myunionB = 100
# Alternatively, you can use an assert
assert isinstance(myunionB, list)
myunionB[2] = 22
甚至更好的是,重新设计代码,这样您就不需要以联合开头,只需将其设为List[int]
。在大多数情况下,尝试尽量减少使用Union类型是一个好主意-经常这样做(尽管并非总是如此!)最终会使您的代码更简单易懂。
类型注释在运行时具有no效果。仅仅因为您已表明myUnionB
应该是int
或ints
的列表,所以您实际上从未defined它是一个列表,更不用说一个至少包含3个元素的了,例如您可以分配给myunionB[2]
。
错误消息可能更清晰; myunionB
是不受支持的目标,因为该名称尚不存在。变量注释不会“创建”变量,因为它不会为要注释的名称分配任何值(甚至是隐式None
)。