嵌套字典的提示类型

时间:2019-10-15 18:33:26

标签: python json dictionary type-hinting

我在Python脚本中解析的数据结构是一个json文件,该文件在$input = 'street'; $n = 2; function outputs($input, $n) { $input = str_replace(' ', '', $input); $characters = str_split($input); $outputs = []; foreach ($characters as $char) { if(!isset($outputs[$char])){ $outputs[$char] = 1; } else { $outputs[$char] += 1; } } foreach ($outputs as $char => $number) { if ($number == $n) { echo $char . ' -> ' . $number; echo "\n"; } } } outputs($input, $n); 之后为json.load(file_handle)类型。到目前为止,一切都很好。现在,对于使用它作为输入参数的函数,我想要解析的json的类型提示。我在typing documentation中读到,对于<class 'dict'>作为参数,我应该使用dict

Mapping[key_type, value_type]

我解析的json具有from typing import Mapping, NoReturn def foo(json_data: Mapping[str, str]) -> NoReturn: ... 型键和str型值,但通常情况下,其结构是高度递归的。因此,一个值更可能是一个具有str键的dict,甚至是诸如值的str。它是非常嵌套的,直到最深层次的最后一个dict最终都具有dict键和str值。

那么,如何更精确地表示此数据结构?我在想一种类似this question的方式,可能是:

str

但是它似乎只代表一种递归水平。有没有更好的方法来提示此内容?

1 个答案:

答案 0 :(得分:2)

简单的格言

您可以简单地将Mapping[K, V]用作另一个Mapping的值。假设您的json看起来像这样:

{
   "person_1": {"money": 1000},
   "person_2": {"money": 1000}
}

在这种情况下,您可以使用如下所示的类型提示:

Mapping[str, Mapping[str, int]]

更严厉的命令

但是,假设您有一些更复杂的东西,例如:

{
    "person_1": {
        "money": 1000,
        "job": "coder",
    }
}

那您怎么键入提示呢?您可以使用Union(来自typing)来执行以下操作:

Mapping[str, Mapping[str, Union[str, int]]]

但是现在我们会遇到诸如mypy之类的工具的问题,认为our_dict["person_1"]["job"]的类型为Union[str, int]

这没错,毕竟这就是我们所说的。可以从[typing_extensions](TypedDict (link to pep explaining it)中引出https://pypi.org/project/typing-extensions/

from typing_extensions import TypedDict

class Person(TypedDict):
    money: int
    job: str

# type hint you would use in your function:
Mapping[str, Person]

注意::Python 3.8 中的TypedDicttyping

的一部分