1

Python 3.6 对此元组示例没有问题:

# tpl is a tuple. Each entry consists of a tuple with two entries. The first
# of those is a tuple of two strings. The second one is a tuple of tuples with
# three strings.

tpl = (
    (('a', 'b'), (('1', '2', '3'), ('4', '5', '6'))),
    (('c', 'd'), (('7', '8', '9'),)),
    )

for first_tuple, second_tuple in tpl:
    str1, str2 = first_tuple
    print(str1, str2)
    for str1, str2, str3 in second_tuple:
        print('   ', str1, str2, str3)
    print()

输出:

a b
    1 2 3
    4 5 6

c d
    7 8 9

但是 mypy 0.511 似乎会感到困惑并报告错误:

ttpl.py:13: error: Iterable expected
ttpl.py:13: error: "object" has no attribute "__iter__"; maybe "__str__"?

我能做些什么来帮助 mypy 了解发生了什么?

4

2 回答 2

3

mypy 默认将元组视为元组,而不是序列 ( Tuple[T, ...])。当您迭代具有不兼容类型的元组时,变量的类型被确定为object

for x in ((1,), (2, 3)):
    reveal_type(x)
    for y in x:
        pass

您可以提供适当的、非常漂亮的类型提示:

from typing import Tuple

tpl: Tuple[Tuple[Tuple[str, str], Tuple[Tuple[str, str, str], ...]], ...] = (
    (('a', 'b'), (('1', '2', '3'), ('4', '5', '6'))),
    (('c', 'd'), (('7', '8', '9'),)),
)

代表真实数据格式的类型别名在这里可能会有所帮助。

于 2017-06-27T06:09:54.410 回答
0

虽然Ryan给出了 python 3.6 的正确答案,也让我了解了正在发生的事情,但我想指出两种替代可能性:

如果您仍然必须使用没有 PEP 526(变量注释语法)的 python 版本,您可以这样做:

from typing import Tuple, Iterable

TypeOfData = Iterable[
    Tuple[
        Tuple[str, str],
        Iterable[Tuple[str, str, str]]
        ]
    ]

tpl = (
    (('a', 'b'), (('1', '2', '3'), ('4', '5', '6'))),
    (('c', 'd'), (('7', '8', '9'),)),
    ) # type: TypeOfData

for first_tuple, second_tuple in tpl:
    str1, str2 = first_tuple
    print(str1, str2)
    for str1, str2, str3 in second_tuple:
        print('   ', str1, str2, str3)
    print()][1]

如果您只想阻止 mypy 报告错误,这也是可能的:

tpl = (
    (('a', 'b'), (('1', '2', '3'), ('4', '5', '6'))),
    (('c', 'd'), (('7', '8', '9'),)),
    )

for first_tuple, second_tuple in tpl:
    str1, str2 = first_tuple
    print(str1, str2)
    for str1, str2, str3 in second_tuple: # type: ignore
        print('   ', str1, str2, str3)
    print()
于 2017-06-27T06:55:14.127 回答