【问题标题】:PyCharm does not recognize dictionary value typePyCharm 无法识别字典值类型
【发布时间】:2016-08-28 21:29:23
【问题描述】:

我有一个简单的代码 sn-p,我将字典值设置为空列表:

new_dict = {}
for i in range(1, 13):
    new_dict[i] = []

现在,如果在下一行的循环中输入 new_dict[i] 并添加一个点,我希望 PyCharm 向我显示可用于 list 的方法列表,但 PyCharm 无法识别字典值类型在这个简单的例子中:

为什么会发生这种情况,我该怎么办?使用 PyCharm 2016.1.2、Python 2.7.10。


作为一种解决方法,我可以显式添加 type hint,通过添加 # type: dict[int, list] 内联注释让 PyC​​harm 知道 new_dict 是一个字典,其中键是整数,值是列表:

【问题讨论】:

  • 请记住,类型提示是在不运行任何代码的情况下进行的。我想不出很多情况下它能够可靠地猜测字典中存储了哪种数据。
  • 如果在可以确定类型是什么的情况下实现了自动类型提示,那么我想很多人会抱怨它有问题/很少正常工作。您发布的示例或任何 python 文字的等效示例,或者可能是返回值被注释的函数调用,是我看到它运行良好的唯一时间。
  • 由于键的“值”,值对几乎可以是任何东西,我认为要求 PyCharm 自动猜测值对象的类型非常困难。正如@TadhgMcDonald-Jensen 所说,PyCharm 实际上并没有运行你的 Python 代码,所以它不知道类型。似乎类型提示在这里是一个不错的选择。
  • 似乎可以合理预期正上方的new_dict[i] = [] 是一个足够的类型提示,但我认为“静态类型”风格的提示更容易解析。
  • 类型提示的工作原理实际上已经给我留下了深刻的印象

标签: python list dictionary pycharm type-hinting


【解决方案1】:

我认为您期望 PyCharm 能够从代码中推断出太多东西。

提供类型提示注释为 PyCharm 提供了显示代码完成选项所需的信息。在这种情况下,您明确告诉 PyCharm 每个字典元素的值将是什么类型。

如果没有类型提示注释,您期望 PyCharm 在循环内分配字典的元素值时能够知道它的值。对于 PyCharm 来说,这太过分了。正如 Tadhg McDonald-Jensen 在 cmets 中提到的那样,这种情况过于动态,PyCharm 无法可靠地计算出来。代码补全会经常出错。

【讨论】:

    【解决方案2】:

    让我们考虑一个稍微复杂的带有变量的场景:

    for i in range(10):
        if i%2:
            x = 3
        else:
            x = "hello"
        x. #type hint for both int and str
    

    在这种情况下,最后一行将为我们提供 ints 和 strs 的所有方法,因为 PyCharm 能够检测到 x 将是 intstr

    现在将所有出现的x 替换为my_dict[i]

    my_dict = {}
    for i in range(10):
        if i%2:
            my_dict[i] = 3
        else:
            my_dict[i] = "hello"
        my_dict[i]. #no type hint :(
    

    所有相同的规则都适用于上述,我们知道(PyCharm 将能够弄清楚)my_dict[i] 将成为intstr

    但是,如果您不初始化 dict,您希望会发生什么?

    def f(my_dict): #or even (my_dict:dict)
        my_dict[1]. #cannot possibly expect a type hint
    

    在这种情况下,除了像在示例案例中那样添加显式注释之外,无法知道 dict 的值是什么:

    def f(my_dict:"dict[int,list]"):
        my_dict[1]. #get all the list methods
    

    这确实强化了The Zen of Python 中的一些内容:

    显式优于隐式。
    可读性很重要。
    面对模棱两可,拒绝猜测的诱惑。
    应该有一种——最好只有一种——明显的方法。

    (我包括可读性,因为显式类型提示比潜在的隐藏赋值更容易阅读)

    【讨论】:

      猜你喜欢
      • 2014-08-28
      • 2018-03-27
      • 2021-08-22
      • 2013-03-06
      • 2014-05-21
      • 2021-10-09
      • 2017-05-22
      • 1970-01-01
      • 2021-11-05
      相关资源
      最近更新 更多