当前位置: 首页 > 知识库问答 >
问题:

Mypy错误-分配中的类型不兼容

解高昂
2023-03-14

我的函数类似于以下简化代码示例:

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

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

当我运行Mypy(版本0.52)我得到这个错误:

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

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

共有1个答案

郎灿
2023-03-14

问题是mypy推断出结果变量的类型是Dict[str,bool],这是因为您第一次在第2行初始化它。

因此,当你稍后尝试插入str时,mypy(理所当然地)会抱怨。您有几个选项来修复您的代码,我将按至少到大多数类型安全的顺序列出这些选项。

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

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一个提示,说明结果应该是什么类型,以帮助其推理过程。

如果您使用Python 3.6,您可以使用以下替代语法注释该行,该语法使用变量注释(自Python 3.6起是新的):

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

选项2的类型安全性稍高一些——使用Union将值声明为strs或bools,而不是别的。这不是完全的类型html" target="_blank">安全,但至少你还可以对你的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

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

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

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

选项3是类型最安全的,尽管它确实要求您使用实验性的“TypeDector”类型,这可以让您将特定类型分配给判决中的不同字段。也就是说,使用这种类型要自担风险——AFAIK它还没有被添加到PEP 484中,这意味着其他类型检查工具(如皮魅力的检查器)没有义务理解这一点。Mypy本身最近才添加了对TypeDector的支持,因此可能仍然存在缺陷:

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包。

 类似资料:
  • 我有下面的Python片段,正在生成MyPy的问题(在vscode)。 错误是: 参数3到ioctl具有不兼容类型my_struct;期望联合[int, str] MyStruct是一个ctypes结构。将与ctypes结构一起使用的所有示例都显示了将实例传递给。事实上,这确实有效,但现在MyPy正在抱怨。 我不希望转换成字节,而是使用模块手动打包/解包(我认为这是一种解决方案)。 我正在使用在L

  • 我一直试图编译这个简单的警报对话框,以便在用户单击提交按钮时显示。编译代码时会弹出一条错误消息: 错误:(33,74)错误:不兼容的类型: 这个类叫做Login_Activity,它扩展了BaseActivity,它扩展了Activity。

  • 我有下面的Kotlin代码。一个名为的密封类和两个对象类和继承自密封类。我在is Cat情况下的子句中得到这个错误。 为什么会给出这个错误?如何使用Kotlin中的密封类来进行这种类型的操作?密封类是做多态的好选择吗?

  • 问题内容: 我正在学习Java。我试图运行代码,但出现此错误:。它向我显示错误的代码部分。 为什么会这样呢? 问题答案: 这是因为在类中不能有两个具有相同名称但返回类型不同的方法。 子类不能使用与返回类型不同的超类中已经存在的方法相同的名称声明方法。 但是,子类可以声明具有与超类相同的签名的方法。我们称此为“覆盖”。 你需要这个 要么 一个好的做法是通过注释标记覆盖的方法:

  • 将以下代码转换为typescript时出错。 错误TS2339:属性样式在元素类型上不存在。 当我为如下相同的值分配所需值时 那么误差在元素上,那就是 错误TS2322:类型“Element | null”不可分配给类型“{style:any;}”。类型“null”不可分配给类型“{style:any;}”。

  • 我们有: 在models.py 在serializers.py 当我通过mypy检查它时: 资源/序列化程序。py:67:错误:赋值中的类型不兼容(表达式的类型为“Union[Any,object]”,变量的类型为“int”) 请通过mypy进行检查: 资源/serializers.py:68:错误:查找'language_id'的不兼容类型:(得到了"Union[any,对象]",预期为"Uni