Mypy 错误 "Need more than 2 values to unpack (3 expected)" 尽管使用了不同元组的并集
Mypy error "Need more than 2 values to unpack (3 expected)" although union of different tuples is used
当我 运行 mypy 使用以下代码时,我得到
Need more than 2 values to unpack (3 expected)
我该如何解决这个问题?
def func(third: bool = False) -> tuple[int, int] | tuple[int, int, int]:
if third:
return 1, 2, 3
else:
return 1, 2
a, b, c = func(True) # mypy error line
在这种情况下,func
实际上返回了三个值。我正在使用 Python 3.10.4.
这是 Mypy 的一个已知问题:Cannot unpack Union of Tuples of different length。
这是我如何修复给定示例的建议,因此它可以工作并且 Mypy 没有显示错误:
from typing import Optional, Tuple
def func(third: bool = False) -> Tuple[int, int, Optional[int]]:
if third:
return 1, 2, 3
else:
return 1, 2, None
a, b, c = func(True)
print(a, b, c)
输出:
1 2 3
Mypy运行:
Success: no issues found in 1 source file
您可以使用 overload
来声明 func
具有不同的 return 类型,具体取决于参数。
from typing import Literal, overload
@overload
def func(third: Literal[True]) -> tuple[int, int, int]:
...
@overload
def func(third: Literal[False]) -> tuple[int, int]:
...
def func(third: bool = False):
if third:
return 1, 2, 3
else:
return 1, 2
描述的情况是 overloading 的典型用例。
您可以注释该函数,这样对于 True
参数它是 return 的 3 元组和对于 False
- 2 元组:
from typing import overload, Literal
@overload
def func(third: Literal[True]) -> tuple[int, int, int]:
...
@overload
def func(third: Literal[False] = ...) -> tuple[int, int]:
...
def func(third: bool = False) -> tuple[int, int] | tuple[int, int, int]:
if third:
return 1, 2, 3
else:
return 1, 2
a, b, c = func(True)
a, b = func(False)
a, b = func()
您当前代码中的问题是 mypy
不知道 return 类型是二元组还是三元组。它不会对实现做出额外的假设,类型提示是严格的。您的代码可能如下所示(mypy
以完全相同的方式解释):
import random
def func(three: bool = False) -> tuple[int, int] | tuple[int, int, int]:
if random.random() < 0.5:
return 1, 1
else:
return 1, 1, 1
a, b, c = func()
... 现在您的代码在(大约)50% 的情况下失败并且 mypy
指向该错误。
当我 运行 mypy 使用以下代码时,我得到
Need more than 2 values to unpack (3 expected)
我该如何解决这个问题?
def func(third: bool = False) -> tuple[int, int] | tuple[int, int, int]:
if third:
return 1, 2, 3
else:
return 1, 2
a, b, c = func(True) # mypy error line
在这种情况下,func
实际上返回了三个值。我正在使用 Python 3.10.4.
这是 Mypy 的一个已知问题:Cannot unpack Union of Tuples of different length。
这是我如何修复给定示例的建议,因此它可以工作并且 Mypy 没有显示错误:
from typing import Optional, Tuple
def func(third: bool = False) -> Tuple[int, int, Optional[int]]:
if third:
return 1, 2, 3
else:
return 1, 2, None
a, b, c = func(True)
print(a, b, c)
输出:
1 2 3
Mypy运行:
Success: no issues found in 1 source file
您可以使用 overload
来声明 func
具有不同的 return 类型,具体取决于参数。
from typing import Literal, overload
@overload
def func(third: Literal[True]) -> tuple[int, int, int]:
...
@overload
def func(third: Literal[False]) -> tuple[int, int]:
...
def func(third: bool = False):
if third:
return 1, 2, 3
else:
return 1, 2
描述的情况是 overloading 的典型用例。
您可以注释该函数,这样对于 True
参数它是 return 的 3 元组和对于 False
- 2 元组:
from typing import overload, Literal
@overload
def func(third: Literal[True]) -> tuple[int, int, int]:
...
@overload
def func(third: Literal[False] = ...) -> tuple[int, int]:
...
def func(third: bool = False) -> tuple[int, int] | tuple[int, int, int]:
if third:
return 1, 2, 3
else:
return 1, 2
a, b, c = func(True)
a, b = func(False)
a, b = func()
您当前代码中的问题是 mypy
不知道 return 类型是二元组还是三元组。它不会对实现做出额外的假设,类型提示是严格的。您的代码可能如下所示(mypy
以完全相同的方式解释):
import random
def func(three: bool = False) -> tuple[int, int] | tuple[int, int, int]:
if random.random() < 0.5:
return 1, 1
else:
return 1, 1, 1
a, b, c = func()
... 现在您的代码在(大约)50% 的情况下失败并且 mypy
指向该错误。