【问题标题】:Recursive type annotations递归类型注解
【发布时间】:2018-12-05 18:55:16
【问题描述】:

我正在尝试在适用的情况下将静态类型注释引入我的代码库。一种情况是在读取 JSON 时,结果对象将是一个以字符串为键的字典,其值为以下类型之一:

  • bool
  • str
  • float
  • int
  • list
  • dict

但是,上面的 listdict 可以包含相同类型的字典,从而导致递归定义。这在 Python3 的类型结构中可以表示吗?

【问题讨论】:

  • JSONVal = Union[blah, blah, blah, List['JSONVal'], Dict[str, 'JSONVal']] 和将 JSON 值注释为 JSONVal 是否有效?
  • 我看到了一个关于递归类型的 mypy issue,这似乎表明这是不可能的,尽管我还没有阅读全部内容。
  • @user2357112 该问题链接非常有帮助。底部附近的一条评论似乎解决了问题:在专门针对 JSON 进行了几次变通后,他们注意到“可悲的是,Dict[str, Any] 大部分时间都是游戏的名称。”
  • 另一种探索方法是TypedDict。如果您确切地知道收到的 JSON 是什么样子,它们会很有用:例如,当调用一些总是返回以固定方式结构化的 JSON 的 API 时。此外,如果您想在运行时验证您的 JSON,我建议使用 Dict[str, object] 而不是 Dict[str, Any]:它会帮助您确认您在正确的位置添加了 isinstance 检查和内容。如果您不关心运行时验证,则转换为 TypedDict 或使用 Dict[str, Any] 可能是正确的选择。
  • @Michael0x2a 这是一个很好的参考,但不——我对运行时收到的 JSON 一无所知,所以我无法以任何有意义的方式验证它。

标签: python python-3.x typing


【解决方案1】:

从 mypy 0.641 开始,mypy 不支持您正在寻找的那种递归类型注释。自然语法:

from typing import Union, Dict, List

JSONVal = Union[None, bool, str, float, int, List['JSONVal'], Dict[str, 'JSONVal']]

d: JSONVal = {'a': ['b']}

产生一个错误,报告缺少递归类型支持:

$ mypy asdf.py
asdf.py:3: error: Recursive types not fully supported yet, nested types replaced with "Any"

另请参阅mypy issue tracker thread 了解递归类型支持。

目前,Dict[str, Any] 可能是要走的路。

【讨论】:

    猜你喜欢
    • 2012-10-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多