Python 及其社区正在努力解决“结构”问题:如何将相关值最好地分组到允许逻辑/轻松访问组件(通常按名称)的复合数据对象中。有许多种相互竞争的方法:
-
collections.namedtuple 实例
- 字典(带有一组固定/已知的键)
- 属性可访问的字典(如stuf)
-
attrs 库
- PEP 557 dataclasses
- 为每种结构类型手工制作的普通旧定制对象
-
tuple 和 list 等序列对每个位置/插槽都有隐含含义(过时但非常常见)
- 等
“应该有一种——最好只有一种——明显的方法。”
typing 库和 Mypy 与整个 Python 社区一样,都在努力解决如何更有效地定义类型/模式,包括复合对象。您链接到的讨论是摔跤的一部分,并试图找到前进的道路。
NamedTuple 是由collections.namedtuple 工厂产生的结构化对象的类型超类; TypedDict Mypy 尝试定义使用固定模式字典时出现的键和相应类型的值。如果您只是在考虑“我有一组固定的键,应该映射到一组固定的类型值”,它们是相似的。但是由此产生的实现和约束是非常不同的。袋子和盒子一样吗?可能是。也许不吧。取决于您的观点以及您希望如何使用它们。倒酒,开始讨论!
NamedTuple,顺便说一下,现在是 Python 的正式部分。
from typing import NamedTuple
class Employee(NamedTuple):
name: str
id: int
TypedDict 最初是作为一个实验性的 Mypy 功能来解决输入到异构的、面向结构的字典使用的问题。然而,从 Python 3.8 开始,它被采用到标准库中。
try:
from typing import TypedDict # >=3.8
except ImportError:
from mypy_extensions import TypedDict # <=3.7
Movie = TypedDict('Movie', {'name': str, 'year': int})
基于类的类型构造函数is also available:
class Movie(TypedDict):
name: str
year: int
尽管存在差异,NamedTuple 和TypedDict 都锁定了要使用的特定键,以及每个键对应的值类型。因此,他们的目标基本相同:为复合/结构类型提供有用的类型化机制。
Python 的标准 typing.Dict 专注于更同质的并行映射,定义键/值类型,而不是键本身。因此,它在定义碰巧存储在字典中的复合对象时不是很有用。
ConnectionOptions = Dict[str, str]