自引用 mypy 类型中的“无效类型”错误

问题描述 投票:0回答:1

我定义了以下类型:

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]

谢谢!

python python-typing mypy
1个回答
2
投票

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

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

线程中的主要阻碍(例如“我们应该首先实现结构子类型”)是正在积极开发中,希望在接下来的几个月内至少成为 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 写了一个如何使用它的示例这个(基本上不相关)答案

© www.soinside.com 2019 - 2024. All rights reserved.