猿问

Python / mypy 中 NamedTuple 和 TypedDict 的主要区别是什么

在我看来,NamedTupleTypedDict非常相似,Python 开发人员自己也认识到了这一点。

关于 PEP,我宁愿添加一个关于 NamedTuple 和 TypedDict 的公共部分,它们非常相似,后者在结构上已经表现得很好。你怎么看? 

但是Guido似乎对此不太确定。

我不太确定 NamedTuple 和 TypedDict 是否真的那么相似(除了它们都试图在静态类型的世界中处理过时的模式)。


所以,这是我懒惰的尝试,让其他人在官方文档似乎缺乏的情况下提出清晰的比较。


素胚勾勒不出你
浏览 313回答 2
2回答

慕慕森

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

喵喵时光机

NamedTuple如果可能的话,如果我想冻结这些值,我会去。否则我会使用数据类。from dataclasses import dataclassfrom typing import NamedTuple, TypedDictfrom enum import Enumclass Gender(Enum):    MALE = "male"    FEMALE = "female"## Class definition: Almost the same@dataclassclass UserDataC:    name: str    gender: Genderclass UserTuple(NamedTuple):    name: str    gender: Genderclass UserNDict(TypedDict):    name: str    gender: Gender## Object Creation: Looks the sameanna_datac = UserDataC(name="Anna", gender=Gender.FEMALE)anna_tuple = UserTuple(name="Anna", gender=Gender.FEMALE)anna_ndict = UserNDict(name="Anna", gender=Gender.FEMALE)## Mutable values vs frozen valuesanna_datac.gender = Gender.MALE# anna_tuple.gender = Gender.MALE  # AttributeError: can't set attributeanna_ndict["gender"] = Gender.MALE# AttributeError: 'dict' object has no attribute 'gender'# anna_ndict.gender = Gender.MALE## New attribute# Note that you can add new attributes like this.# Python will not complain. But mypy will.anna_datac.password = "secret"  # Dataclasses are extensible# anna_tuple.password = "secret"  # AttributeError - named tuples not# anna_ndict.password = "secret"  # AttributeError - TypedDict notanna_ndict["password"] = "secret"## isinstanceassert isinstance(anna_tuple, tuple)assert isinstance(anna_ndict, dict)为什么我更喜欢 NamedTuple 而不是 namedtuple我认为写和读更直观。另外,您可以为 mypy 提供更多检查的可能性:class UserTuple(NamedTuple):    name: str    gender: Gender# vsUserTuple = namedtuple("UserTuple", ["name", "gender"])为什么我更喜欢元组而不是字典如果我不需要事物可变,我喜欢它们不是可变的。这样我可以防止意外的副作用
随时随地看视频慕课网APP

相关分类

Python
我要回答