我正在尝试将一个冗长的空洞"数据"类转换为一个命名元组.我的班级目前看起来像这样:
class Node(object):
def __init__(self, val, left=None, right=None):
self.val = val
self.left = left
self.right = right
Run Code Online (Sandbox Code Playgroud)
转换为namedtuple它后看起来像:
from collections import namedtuple
Node = namedtuple('Node', 'val left right')
Run Code Online (Sandbox Code Playgroud)
但这里有一个问题.我的原始类允许我传入一个值,并使用命名/关键字参数的默认值来处理默认值.就像是:
class BinaryTree(object):
def __init__(self, val):
self.root = Node(val)
Run Code Online (Sandbox Code Playgroud)
但是这对我重构的名为元组的情况不起作用,因为它希望我传递所有字段.当然,我可以代替的出现Node(val)到Node(val, None, None),但它不是我的胃口.
所以确实存在着一个很好的技巧,它可以使我重新写成功无需添加大量的代码复杂度(元编程),或者我应该只吞下药丸,并与"查找和替换"继续前进?:)
使用PEP 557,数据类被引入到python标准库中.
他们使用@dataclass装饰器,他们应该是"默认的可变的命名元组",但我不确定我理解这实际意味着什么,以及它们与普通类的区别.
究竟什么是python数据类以及何时最好使用它们?
PEP-557引入了数据类到Python标准库,基本上可以填补因为同样的作用collections.namedtuple和typing.NamedTuple.现在我想知道如何分离使用namedtuple仍然是更好的解决方案的用例.
当然,dataclass如果我们需要,所有的功劳都归功于:
property 装饰器,可管理的属性在同一个PEP中简要解释了数据类的优点:为什么不使用namedtuple.
但是对于namedtuples这个相反的问题怎么样:为什么不使用dataclass呢?我想从性能的角度来看,名字元组可能更好,但尚未确认.
让我们考虑以下情况:
我们将页面维度存储在一个小容器中,该容器具有静态定义的字段,类型提示和命名访问.不需要进一步散列,比较等.
NamedTuple方法:
from typing import NamedTuple
PageDimensions = NamedTuple("PageDimensions", [('width', int), ('height', int)])
Run Code Online (Sandbox Code Playgroud)
DataClass方法:
from dataclasses import dataclass
@dataclass
class PageDimensions:
width: int
height: int
Run Code Online (Sandbox Code Playgroud)
哪种解决方案更可取,为什么?
PS这个问题不是以任何方式重复那个问题,因为我在这里询问的是哪个命名元组更好,而不是区别(我在询问之前检查了文档和来源)