Python and its community are wrestling with the "struct" problem: how to best group related values into composite data objects that allow logical/easy accessing of components (typically by name). There are many competing approaches:
collections.namedtuple
instances
- dictionaries (with a fixed/known set of keys)
- attribute-accessible dictionaries (like stuf)
- the attrs library
- PEP 557 dataclasses
- plain old bespoke objects hand-crafted for every struct type
- sequences like
tuple
and list
with implied meanings for each position/slot (archaic but extremely common)
- etc.
So much for "There should be one—and preferably only one—obvious way to do it."
Both the typing
library and Mypy, like the Python community at large, are simultaneously struggling with how to more effectively define types/schema, including for composite objects. The discussion you linked to is part of that wrestling and trying to find a way forward.
NamedTuple
is a typing superclass for structured objects resulting from the collections.namedtuple
factory; TypedDict
a Mypy attempt to define the keys and corresponding types of values that occur when using fixed-schema dictionaries. They are similar if you're just thinking about "I have a fixed set of keys that should map to a fixed set of typed values." But the resulting implementations and constraints are very different. Are a bag and a box similar? Maybe. Maybe not. Depends on your perspective and how you want to use them. Pour wine and let the discussion begin!
NamedTuple
, by the way, is now a formal part of Python.
from typing import NamedTuple
class Employee(NamedTuple):
name: str
id: int
TypedDict
started life as an experimental Mypy feature to wrangle typing onto the heterogeneous, structure-oriented use of dictionaries. As of Python 3.8, however, it was adopted into the standard library.
try:
from typing import TypedDict # >=3.8
except ImportError:
from mypy_extensions import TypedDict # <=3.7
Movie = TypedDict('Movie', {'name': str, 'year': int})
A class-based type constructor is also available:
class Movie(TypedDict):
name: str
year: int
Despite their differences, both NamedTuple
and TypedDict
lock down the specific keys to be used, and the types of values corresponding to each key. Therefore they are aiming at basically the same goal: Being useful typing mechanisms for composite/struct types.
Python's standard typing.Dict
focuses on much more homogenous, parallel mappings, defining key/value types, not keys per se. Therefore it is not very useful in defining composite objects that happen to be stored in dictionaries.
ConnectionOptions = Dict[str, str]
namedtuple
&dict
look similar to you? – MiddendorfNamedTuple
andTypedDict
one should first understand the difference betweennamedtuple
anddict
. – CytosineNamedTuple
/TypedDict
/etc. alternative that is covariant rather than invariant. Something like a “TypedMapping
” (in analogy toMapping
vsdict
). – Atthia