Mypy 错误 - 赋值中的类型不兼容 [英] Mypy error - incompatible types in assignment

查看:42
本文介绍了Mypy 错误 - 赋值中的类型不兼容的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的函数看起来像这个简化的代码示例:

My function looks like this simplified code sample:

def my_func() -> dict:
    result = {"success": False}

    if condition:
        result["success"] = True
        return result
    else:
        result["message"] = "error message"
    return result

当我运行 Mypy(0.52 版)时出现此错误:

When I run Mypy (version 0.52) I get this error:

error: Incompatible types in assignment (expression has type "str", target has type "bool")

并且错误指向我的代码示例中的倒数第二行.为什么 mypy 返回此错误?我的代码无效(以任何方式)还是这是一些 mypy 错误?

and the error is pointing to the second last line in my code sample. Why mypy is returning this error? is my code invalid (in any way) or is this some mypy bug?

推荐答案

问题是mypy推断你的result变量的类型是Dict[str, bool] 由于您在第 2 行首次初始化它的方式.

The problem is that mypy inferred that the type of your result variable is Dict[str, bool] due to how you first initialized it on line 2.

因此,当您稍后尝试插入 str 时,mypy(理所当然地)会抱怨.您有多种修复代码的选项,我将按类型安全从低到高的顺序列出.

Consequently, when you try and insert a str later, mypy (rightfully) complains. You have several options for fixing your code, which I'll list in order of least to most type-safe.

选项 1 是声明您的字典,使其值属于 Any 类型——也就是说,您的值根本不会进行类型检查:

Option 1 is to declare your dictionary such that its values are of type Any -- that is, your values will not be type-checked at all:

from typing import Any, Dict

def my_func(condition: bool) -> Dict[str, Any]:
    result = {"success": False}  # type: Dict[str, Any]

    if condition:
        result["success"] = True
    else:
        result["message"] = "error message"
    return result

请注意,我们需要对您的第二行进行注释,以便为 mypy 提供关于 result 的类型应该是什么的提示,以帮助其推理过程.

Note that we needed to annotate your second line to give mypy a hint about what the type of result should be, to help its inference process.

如果您使用的是 Python 3.6+,则可以使用以下替代语法对该行进行注释,该语法使用变量注释(Python 3.6 中的新内容):

If you're using Python 3.6+, you can annotate that line using the following alternate syntax, which uses variable annotations (which are new as of Python 3.6):

result: Dict[str, Any] = {"success": False}

选项 2 的类型安全性更高——使用 Union 将您的值声明为 strs 或 bool,但仅此而已.这不是完全类型安全的,但至少你仍然可以对你的字典进行一些检查.

Option 2 is slightly more type-safe -- declare your values to be either strs or bools, but nothing else, using Union. This isn't fully typesafe, but at least you can still have some checks on your dict.

from typing import Any, Dict

def my_func(condition: bool) -> Dict[str, Union[str, bool]]:
    result = {"success": False}  # type: Dict[str, Union[str, bool]]

    if condition:
        result["success"] = True
    else:
        result["message"] = "error message"
    return result

您可能会发现该类型注释有点长/输入起来很烦人,因此您可以使用类型别名来提高可读性(并且可以选择使用变量注释语法),如下所示:

You may perhaps find that type annotation to be a little long/annoying to type, so you could use type aliases for readability (and optionally use the variable annotation syntax), like so:

ResultJson = Dict[str, Union[str, bool]]

def my_func(condition: bool) -> ResultJson
    result: ResultJson = {"success": False}
    # ...snip...

选项 3 是最类型安全的,尽管它确实要求您使用实验性的TypedDict"类型,它允许您将特定类型分配给字典中的不同字段.也就是说,使用这种类型的风险由您自己承担——AFAIK 它还没有被添加到 PEP 484 中,这意味着其他类型检查工具(如 Pycharm 的检查器)没有义务理解这一点.Mypy 本身最近才添加了对 TypedDict 的支持,因此可能仍有问题:

Option 3 is the most type-safe, although it does require you to use the experimental 'TypedDict' type, which lets you assign specific types to different fields in your dict. That said, use this type at your own risk -- AFAIK it hasn't yet been added to PEP 484, which means other type-checking tools (like Pycharm's checker) aren't obligated to understand this. Mypy itself only recently added support for TypedDict, and so may still be buggy:

from typing import Optional
from mypy_extensions import TypedDict

ResultJson = TypedDict('ReturnJson', {'success': bool, 'message': Optional[str]})

def my_func(condition: bool) -> ResultJson:
    result = {"success": False, "message": None}  # type: ResultJson

    if condition:
        result["success"] = True
    else:
        result["message"] = "error message"
    return result

如果要使用此选项,请务必安装 mypy_extensions 包.

Be sure to install the mypy_extensions package if you want to use this option.

这篇关于Mypy 错误 - 赋值中的类型不兼容的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆