20

Python 3.7 提供了dataclasses具有预定义特殊功能的新功能。

从概述的角度来看,dataclasses两者SimpleNamespace都提供了很好的数据封装工具。

@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. 有人如何在 和 之间SimpleNamespace进行选择dataclasses
  2. 为什么它们是必要的,当扩展SimpleNamespace?
  3. 所有其他用例都dataclasses迎合什么?
4

2 回答 2

10

Dataclasses 更像是namedtuple流行的attrs包(甚至在PEPSimpleNamespace中都没有提到)。它们有两种不同的预期目的。

数据类

  • 结构化的
  • 键入(默认情况下,但可选)
  • 为基本的 dunder 方法(、、、__init__等等__hash____eq__编写大部分样板文件
  • 为属性的默认值提供简单的机制
  • 可以轻松添加__slots__和方法

简单命名空间

  • “抓包”数据结构
  • 用于您需要的不仅仅是字典但不需要类的地方
  • 不打算使用类似的东西__slots__

SimpleNamespace文档中:

SimpleNamespace 可用于替代class NS: pass. 但是,对于结构化记录类型,请namedtuple()改用。

由于@dataclass应该替换很多用例namedtuple,命名记录/结构应该使用@dataclass,而不是SimpleNamespace

您可能还想看看Raymond Hettinger 的这个 PyCon 演讲,他在其中介绍了它的背景故事@dataclass和它的用途。

于 2018-06-29T14:02:18.367 回答
6

简短的回答是PEP 557涵盖了所有内容。把你的问题稍微弄乱了......

为什么?

  1. 利用 PEP 526 提供定义此类类的简单方法。
  2. 支持静态类型检查器。

如何选择何时使用它们?

PEP 非常清楚它们不是替代品,并希望其他解决方案有自己的位置。

因此,与任何其他设计决策一样,您需要准确确定您关心的功能。如果这包括以下内容,您肯定不想要数据类。

哪些地方不适合使用数据类?

需要与元组或字典的 API 兼容性。需要超出 PEP 484 和 526 提供的类型验证,或者需要值验证或转换。

也就是说,SimpleNameSpace 也是如此,那么我们还能看什么来决定呢?让我们仔细看看数据类提供的额外功能......

SimpleNameSpace 的现有定义如下:

一个简单的对象子类,提供对其命名空间的属性访问,以及有意义的 repr。

然后 python 文档继续说它提供了一个简单的__init__,__repr____eq__实现。将此与 PEP 557 进行比较,数据类还为您提供以下选项:

  • ordering - 按顺序比较类,就好像它是其字段的元组一样。
  • 不变性 - 分配给字段将产生异常
  • 控制散列 - 尽管不建议这样做。

显然,如果您关心排序或不变性(或需要小众散列控制),则应该使用数据类。

其他用例?

我看不到,尽管您可以争辩说最初的“为什么?” 涵盖其他用例。

于 2018-06-29T11:54:40.150 回答