【问题标题】:"invalid type" error in self-referential mypy types自引用 mypy 类型中的“无效类型”错误
【发布时间】:2017-11-16 21:41:50
【问题描述】:

我定义了以下类型:

KRPCTypes = typing.Union[int, bytes, list, "KRPCDict"]
KRPCDict = typing.Dict[bytes, KRPCTypes]

当我运行mypy 时,我收到以下错误:

error: Invalid type "test.KRPCDict"

这是重现错误的完整最小代码:

import typing

KRPCTypes = typing.Union[int, bytes, list, "KRPCDict"]
KRPCDict = typing.Dict[bytes, KRPCTypes]

谢谢!

【问题讨论】:

  • 显然 mypy 还不支持递归类型:github.com/python/mypy/issues/731(引用主要开发人员的话:“我目前的计划是将递归类型推迟到简单的结构子类型出现后再重新考虑它们。在考虑了它们之后它们会增加很多复杂度
  • 那么基于字符串文字的版本:Tree_Type = TypeVar('Tree_Type', bound='Tree')Tree = Dict[str, Union[Tree_Type, str]](对于 str-paths→str 的树)呢?我没有进行过深入的测试,但就我的测试而言,这是有效的。

标签: python static-typing mypy


【解决方案1】:

不幸的是,mypy 和 Python 类型化生态系统目前不支持递归类型。

你可以在这里找到它的问题:https://github.com/python/mypy/issues/731(尽管你应该忽略中间的一些帖子,因为它们是由最终遇到无关问题的人发布的)。

线程中的主要阻塞器(例如“我们应该首先实现结构子类型化”)是under active development,希望在接下来的几个月内至少应该成为 mypy 的一部分,所以也许值得重新讨论。

目前许多人倾向于使用的解决方法(尤其是在尝试键入 JSON 时,您的类型类似于)是手动将递归类型扩展到所需的级别,并最终使用Any 触底。例如:

from typing import Union, Dict, List, Any

KRPCTypes = Union[int, bytes, list, Dict[bytes, Union[int, bytes, list, Any]]]
KRPCDict = Dict[bytes, KRPCTypes]

顺便说一下,您可能想要使用typing.List[T] 并指定列表应该包含的类型——如果您只使用list,它默认为typing.List[Any],它可能不太精确。

另一种方法可能是使用实验性的TypedDict 类型,它允许您定义给定字典的确切类型和结构。这不太有用,因为 TypedDict 不能代表每一种 KRPCDict,但如果您希望只处理有限数量的不同类型的 KRPCDict 类型,它会派上用场。

目前还没有关于 TypedDict 的文档(开发人员希望在发布之前先解决所有主要错误),但是如果您想尝试修改它,我写了一个示例,说明您将如何使用它bottom of this (largely unrelated) answer.

【讨论】:

    猜你喜欢
    • 2020-02-23
    • 2020-06-12
    • 1970-01-01
    • 2016-09-30
    • 2021-11-29
    • 1970-01-01
    • 2017-10-10
    • 1970-01-01
    相关资源
    最近更新 更多