PyCharm 中类型提示 dict.items() 时的奇怪行为

Posted

技术标签:

【中文标题】PyCharm 中类型提示 dict.items() 时的奇怪行为【英文标题】:Strange behaviour when type-hinting dict.items() in PyCharm 【发布时间】:2021-06-13 04:29:04 【问题描述】:

假设我有一个函数,do_something:

from typing import Sequence, Tuple, Dict

def do_something(argument: Sequence[Tuple[int, str]]):
    pass

假设我还有一本字典,D,其键仅为ints,其值仅为strs:

D: Dict[int, str] = 1: 'a', 2: 'b', 3: 'c'

在 PyCharm 中,这将出色地通过类型检查器:

do_something(
    ((1, 'a'), (2, 'b'), (3, 'c'))
)

但是,根据 PyCharm 的说法,尽管它产生的内容相同,但类型检查器却失败了:

do_something(tuple(D.items()))

这是预期的行为 - 我在这里遗漏了什么吗? -- 或者这是 PyCharm 的类型检查器的错误?

【问题讨论】:

【参考方案1】:

这是 PyCharm 中的一个错误。 有许多类似的错误,例如this, this, this.

总的来说,PyCharm 在这方面非常聪明。在您的情况下,它可以正确推断 D 的类型。它还正确地推断出D.items(),然后在for k, v in D.items()kv 之类的代码中将被正确推断。但是由于某些奇怪的原因,tuple/list/sortedD.items() 周围的东西是有问题的。

我总是会在您希望它可以工作时在 Youtrack 上报告问题。

【讨论】:

我仍然很想知道 Mypy 是否适合这个。【参考方案2】:

PyCharm 不能保证D 的类型真的是Dict[str, int];它可能不会进行代码流分析以确保没有任何东西不能将非(str, int) 对添加到字典中。 (顺便说一句,您应该看看 Mypy,Python 的“规范”类型检查器是否可以。)

您也许可以添加显式类型注释以查看是否有帮助。

D: Dict[str, int] = 1: 'a', 2: 'b', 3: 'c'

【讨论】:

有道理,谢谢。是的——我尝试明确指定字典的键和值始终是一致的类型。可悲的是,什么也没做(尽管这显然不是一个大问题)。 如果添加显式类型没有帮助,则可能没有隐式或显式键入说 tuple(x.items()) 对于 xDict[K, V]Sequence[Tuple[K, V]]...跨度> 是的,我认为这是一个更深层次的问题。我尝试将函数本身中的类型提示调整为:def DoSomething(argument: Sequence[Tuple[Any, Any]]): pass,但问题仍然存在。无论任何给定字典的键和值的类型是什么,在我看来 tuple(Dict.items()) 将始终是 Sequence[Tuple[Any, Any]] 类型。所以这对我来说没有逻辑意义。 嗯...试试Iterable[Tuple[K, V]] - 我认为Sequences 应该是可索引的,但.items()es 肯定不是。 还是不行!从我在另一个答案中被指出的例子来看,它看起来可能只是一个 PyCharm 错误。

以上是关于PyCharm 中类型提示 dict.items() 时的奇怪行为的主要内容,如果未能解决你的问题,请参考以下文章

Python3基础 dict items 以元组的形式打印出字典的每一个项

Python 3字典迭代中的性能:dict [key] vs. dict.items()

在 PyCharm 中隐藏 Python 类型提示

如何在 PyCharm 中显示类型提示?

PyCharm 类型提示怪异

如何在 Pycharm 中输入提示“不返回的返回类型”