在解包元组时使用类型提示?

126

当解包元组时,是否可以使用类型提示?我想这样做,但结果会导致SyntaxError

from typing import Tuple

t: Tuple[int, int] = (1, 2)
a: int, b: int = t
#     ^ SyntaxError: invalid syntax

由于变量的类型已经从解包的值中推断出来,实际上您不需要为它们添加类型提示。 - Jeyekomon
如果类型推断是正确的。假设我的元组来自一个函数 def f() -> Tuple[int, int]: return 1, 2,并且我的解包 a, b = f() 都想要 a: floatb: float - Cai
如果您的函数返回一个整数元组,无论使用哪种类型提示,变量ab都将包含整数。 - Jeyekomon
@Jeyekomon确实,它们会在分配后立即成为浮点数,但如果我知道ab应该是浮点数,并且稍后将包含浮点数,则无论哪个函数给出其初始值或提示是什么,我都希望将它们提示为浮点数。 - Cai
1
我理解你想做什么。重要的是,如果这些变量应该是浮点数并且你将它们类型提示为浮点数,那么你不应该将整数赋值给它们。这不是一个好的编码习惯。任何变量在其生命周期中都不应更改其类型。这会让其他人感到困惑,也会让代码检查工具发出警告。其中一种解决方法是 a, b = (float(x) for x in f()) - Jeyekomon
@Jeyekomon 好的,是的,那是一个非常好的观点。抱歉我之前没有理解你。 - Cai
2个回答

158
根据PEP-0526,你应该先标注类型,然后再进行解包。
a: int
b: int
a, b = t

8
仍会触发警告: 重新声明了已定义但未使用的变量'a'。 - tribbloid
1
@tribbloid 我明白了,当我之前确实已经定义了 a 时会出现这种情况,你确定你没有这样做吗? - joel
1
@tribbloid 如果变量被重新定义,例如 a = int(a) 或其他重新赋值操作,就会出现这种情况。如果您使用 mypy 进行静态类型检查,请使用 --allow-redefinition 来避免警告。 - normanius
7
很遗憾,<variable>:<typehint> 在任何语法上下文中都不能使用,这真是让人沮丧。即使在允许变量赋值的情况下也是如此。 - g.pickardou

5
在我的情况下,我使用typing.cast函数来类型提示解包操作。
t: tuple[int, int] = (1, 2)
a, b = t

# type hint of a -> Literal[1]
# type hint of b -> Literal[2]

使用cast(new_type, old_type),你可以将那些丑陋的文本转换为整数。

from typing import cast

a, b = cast(tuple[int, int], t)

# type hint of a -> int
# type hint of b -> int

当使用Numpy NDArrays中的未知类型时,这可能会很有用。

# type hint of arr -> ndarray[Unknown, Unknown]

a, b = cast(tuple[float, float], arr[i, j, :2]

# type hint of a -> float
# type hint of b -> float

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接