长话短说
PEP-557在Python标准库中引入了数据类,基本上可以充当与集合.namedtuple
和类型.namedtuple
相同的角色。现在我想知道如何区分namedtuple仍然是更好解决方案的用例
数据类相对于NamedTuple的优势
当然,如果我们需要:
- 可变对象
- 继承支持
属性
装饰器,可管理属性- 即时生成的方法定义或可自定义的方法定义
数据类的优势在同一个PEP中简要说明:为什么不使用namedtuple呢
问:在哪种情况下,namedtuple仍然是更好的选择
但是对于namedtuples,一个相反的问题是:为什么不使用dataclass呢?
我想从性能的角度来看,namedtuple可能更好,但还没有得到证实
范例
我们考虑以下情况:
我们将把页面维度存储在一个小容器中,其中包含静态定义的字段、类型提示和命名访问。不需要进一步的散列、比较等
命名双方法:
输入import NamedTuple的
PageDimensions=NamedTuple(“PageDimensions”,[('width',int),('height',int)])
数据类方法:
从数据类导入数据类
@数据类
类页面尺寸:
宽度:int
高度:整数
哪种解决方案更可取?为什么
另外,这个问题在任何方面都不是这个问题的重复,因为我在这里问的是命名双倍更好的案例,而不是差异(我在问之前检查了文档和来源)
这取决于你的需要。他们每个人都有自己的好处
下面是关于PyCon 2018 Raymond Hettinger上数据类的一个很好的解释-数据类:结束所有代码生成器的代码生成器
在Dataclass
中,所有实现都是用Python编写的,而在NamedTuple
中,所有这些行为都是免费的,因为NamedTuple
继承自tuple
。而且由于元组
结构是用C编写的,因此标准方法在命名元组(散列、比较等)中速度更快
还请注意,数据类
基于dict
,而命名元组
基于元组
。因此,使用这些结构有其优点和缺点。例如,使用NamedTuple
,空间使用更少,但使用Dataclass
,时间访问更快
请看我的实验:
[33]on
:a=PageDimensionsDC(宽度=10,高度=10)
At[34]on:sys.getsizeof(a)+sys.getsizeof(vars(a))
168[34]:Out
At[35]on:%timeit a.width
每个回路43.2纳秒±1.05纳秒(7次运行的平均值±标准偏差,每个10000000个回路)
At[36]on:a=PageDimensionsNT(宽度=10,高度=10)
In[37]:sys.getsizeof(a)
Out[37]:64
At[38]:%timeit a.width中
每个回路63.6纳秒±1.33纳秒(7次运行的平均值±标准偏差,每个10000000个回路)
但是随着NamedTuple
属性数量的增加,访问时间保持不变,因为它会为每个属性创建一个具有属性名称的属性。例如,在我们的示例中,新类的命名空间部分如下所示:
来自操作员导入itemgetter的
类名称空间={
...
“宽度”:属性(itemgetter(0,doc=”字段号0的别名),
“高度”:属性(itemgetter(0,doc=”字段号1的别名)**
}
在哪些情况下,命名为tuple仍然是更好的选择
当您的数据结构需要/可以是不可变的、可散列的、可扩展的、可解包的、可比较的时,您可以使用NamedTuple
。如果您需要更复杂的东西,例如,数据结构继承的可能性,那么使用Dataclass