Python 类型提示: Typed Dict

建议点击 查看原文 查看最新内容。

原文链接: https://typonotes.com/posts/2024/11/23/python-hint-typed-dict/

在 Golang 中, 通过 json/yaml 解析对象后, 可以通过提示器快速获取字段

但是 Python 作为动态语言, 这方便的功能就比较弱。 但好在 Python 提供了 TypedDict 进行提示。

typing 是标准库, 不用安装。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
# TypedDict

from typing import TypedDict

class Movie(TypedDict):
    name: str
    year: int

movie: Movie = {
    "name": "Groot",
    "year": 1998,
}

movie["name"] = "Marval"
movie["year"] = 1999

# This will raise a type error in IDE, but can be added while running
movie["director"] = "James Gunn"

print(movie)
# Output: {'name': 'Marval', 'year': 1999, 'director': 'James Gunn'}

在指定了 movie 类型后, IDE 可以对字段进行提示了。

注意: Python 的类型标注可以看错 帮助 IDE 实现静态检查但实际运行时会被忽略。 并非真正地强制约束了类型。

此处虽然 movie["director"] = "James Gunn" 会在 IDE 上提示字段不存在, 但是在实际运行的时候依旧会被添加到 movie 中。

嵌套类型

在字段中引用自定义类型即可, 没有什么需要特别强调的, 类如 addres: Address

注意: Python 代码有优先顺序, 因此 Address 必须优先于 Person 定义, 否则无法引用。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import json
from typing import TypedDict

class Address(TypedDict):
    street: str
    city: str

class Person(TypedDict):
    name: str
    age: int
    addres: Address

def read_person(name: str):
    with open(name, mode="r", encoding="utf-8") as f:
        data = json.load(f)
        # person: Person = data
        # return person
        # 强制类型转换 (标注)
        return Person(data)

person = read_person("person.json")
print(person["addres"])  # {'street': '123 Main St', 'city': 'Springfield'}
print(person["title"])  # Software Engineer

虽然使用了 Person(data) 进行类强制类型转换, 但是实际还是可以使用 person["title] 获取到值。

参考文档

  1. TypedDict: Type Hints for Dictionaries with a Fixed Set of Keys: https://peps.python.org/pep-0589/