【问题标题】:mypy error: error: Value of type "Optional[Dict[Any, Any]]" is not indexablemypy 错误:错误:“Optional [Dict [Any, Any]]”类型的值不可索引
【发布时间】:2021-05-04 11:11:19
【问题描述】:

我有一个小函数,我打错字了,但是我得到了一个 mypy 错误。我查了一下,发现了一些关于强制转换和添加断言的建议,但它们也无济于事。 我正在使用mypy==0.812 和 Python 3.6。有关如何解决此问题的任何提示都会有所帮助。

error: Value of type "Optional[Dict[Any, Any]]" is not indexable

这是函数:

from typing import Union
from datetime import datetime

def _get_number(my_dict: Union[dict, None], relevant_key: Union[str, None]) -> int:
    if my_dict is None:
        return 0
    else:
        # my_dict: dict = cast(dict, my_dict) # adding this didn't help with the mypy error
        # assert isinstance(my_dict, dict) # adding this didn't help with the mypy error
        sorted_keys = sorted(
            my_dict,
            key=lambda k: datetime.strptime(my_dict[k], "%H:%M").time(),
        )
        return sorted_keys.index(relevant_key)

【问题讨论】:

    标签: python-3.x mypy static-code-analysis


    【解决方案1】:

    问题在于,尽管已知my_dict 是声明 lambda 的字典,但 MyPy 不够聪明,无法知道在调用 lambda 时它仍然是字典。在一般情况下,MyPy 将其标记为错误是正确的:

    def test(d: Optional[dict]) -> None:
        if d is not None:
            # d is definitely a dict where the lambda is declared
            f = lambda: print(d['foo'])
            d = None
            # now d is None when the lambda is called
            f()
    

    您的代码与此示例之间的区别在于,my_dict 在声明和调用 lambda 之间没有机会变为 None,因为sorted 立即调用 lambda 然后丢弃它。但 MyPy 不知道这一点,因此它保守地用相同的错误标记您的代码。

    解决方案是使用dict 类型的变量而不是Optional[dict]。您可以通过在检查my_dict 不是None 之后声明一个新变量(如my_actual_dict: dict = my_dict)来实现这一点,然后在lambda 中使用my_actual_dict。由于my_actual_dict 具有静态类型dict,因此MyPy 知道在声明lambda 后不能为其分配值None

    【讨论】:

      【解决方案2】:

      虽然@kaya3 是正确的,但它完全无法使用 lambda 函数来指定所有这些以满足类型检查。我会提供一种替代方法,让 mypy 使用忽略杂注跳过这一行。

      sorted_keys = sorted(
                  my_dict,
                  key=lambda k: datetime.strptime(my_dict[k], "%H:%M").time(),
              ) #type: ignore
      

      【讨论】:

        猜你喜欢
        • 2021-06-14
        • 2020-08-05
        • 2021-12-31
        • 2020-08-29
        • 2019-09-08
        • 2022-07-28
        • 2020-11-05
        • 2021-02-06
        • 2021-07-16
        相关资源
        最近更新 更多