Python 3.7:数据类和SimpleNameSpace的实用性

26

Python 3.7提供了新的dataclasses,其中包括预定义的特殊函数。

从概览的角度来看,dataclassesSimpleNamespace都提供了很好的数据封装功能。

@dataclass
class MyData:
    name:str
    age: int

data_1 = MyData(name = 'JohnDoe' , age = 23)

data_2 = SimpleNamespace(name = 'JohnDoe' , age = 23)

很多时候我使用 SimpleNamespace 来包装数据并移动它。

我甚至会继承它以添加特殊功能:


我甚至会子类化它来添加特殊函数:
from types import SimpleNamespace

class NewSimpleNameSpace(SimpleNamespace):
    def __hash__(self):
        return some_hashing_func(self.__dict__)

对于我的问题:

  1. 某人如何在SimpleNamespacedataclasses之间做出选择?
  2. 当可以通过扩展SimpleNamespace来实现相同的效果时,为什么它们是必要的?
  3. dataclasses适用于哪些其他用例?
  1. 某人如何在SimpleNamespacedataclasses之间做出选择?
  2. 当可以通过扩展SimpleNamespace来实现相同的效果时,为什么需要它们?
  3. dataclasses适用于哪些其他用例?

SimpleNamespace只添加属性和 __repr__。dataclass添加了更多,例如 __eq____hash__等。 - L3viathan
2个回答

15

Dataclasses

Dataclasses 更像是 namedtuple 和流行的 attrs 包,而不是 SimpleNamespacethe PEP中甚至没有提到)。它们有着两个不同的预期用途:

  • 结构化
  • 有类型(默认情况下,但可选)
  • 为基本的双下划线方法(__init____hash____eq__ 等)编写大部分样板代码
  • 提供属性默认值的简单机制
  • 可以轻松添加 __slots__ 和方法

SimpleNamespace

SimpleNamespace 是一种“抓包”数据结构,用于在需要比字典更多但少于类的情况下使用。它不适用于像 __slots__ 这样的东西。

SimpleNamespace 文档中:

SimpleNamespace 可以作为 class NS: pass 的替代品。然而,对于结构化记录类型,应使用 namedtuple()

由于 @dataclass 应该取代许多 namedtuple 的用例,因此命名记录/结构应使用 @dataclass 而不是 SimpleNamespace

你可能也想看看Raymond Hettinger关于PyCon演讲,在那里他深入探讨了@dataclass的背景和使用。


9
简短的回答是这全部都包含在PEP 557中。稍微按不同顺序回答您的问题...
为什么要使用它们?
为了利用PEP 526提供一种定义这些类的简单方法。
为了支持静态类型检查器。
如何选择何时使用它们?
PEP非常清楚地指出,它们不是替代品,并期望其他解决方案有其自己的位置。
像任何其他设计决策一样,因此您需要确定确切关心哪些功能。如果包括以下内容,则绝对不需要使用数据类:
何时不适合使用数据类?
需要与元组或字典的API兼容。
需要超出PEP 484和526所提供的类型验证范围,或需要值验证或转换。
话虽如此,SimpleNameSpace也是如此,那么我们还能看什么来决定呢?让我们更仔细地看一下数据类提供的额外功能...
现有的SimpleNameSpace定义如下:
一个简单的对象子类,提供对其命名空间的属性访问以及有意义的repr。Python文档随后指出它提供了一个简单的 __init__、__repr__ 和 __eq__ 实现。与PEP 557相比,数据类还为您提供以下选项:排序-将类比作其字段的元组,按顺序进行比较;不可变性-分配给字段会生成异常;控制哈希-虽然这不是推荐的做法。因此,如果您关心排序或不可变性(或需要利基哈希控制),则应使用数据类。其他用例?我看不到任何其他用例,尽管您可以认为最初的“为什么?”涵盖了其他用例。

1
我想指出的是,这也取决于您的数据结构化程度。如果有明确的类型/对象模型,则数据类更明确地说明了对象中应该包含什么。此外,像__slots__这样的类特性在数据类中比SimpleNamespace更有意义。 - Edward Minnix
@EdwardMinnix 你能把那写成一个答案吗?这是值得讨论的用例。 - xssChauhan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接