Python 3.7:数据类和SimpleNameSpace的实用程序

时间:2018-06-28 12:02:27

标签: python python-3.7 python-dataclasses

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的所有其他用例还满足哪些需求?

2 个答案:

答案 0 :(得分:5)

数据类更像namedtuple和流行的attrs包,而不是SimpleNamespacethe PEP中甚至没有提到)。它们有两个不同的预期目的。

数据类

  • 结构化
  • 已键入(默认,但可选)
  • 为基本的dunder方法({{1},__init____hash__等)编写大部分样板
  • 为属性的默认值提供简单的机制
  • 可以轻松添加__eq__和方法

SimpleNamespace

  • “抓袋”数据结构
  • 用于需要多于词典但少于一堂课的地方
  • 不打算使用__slots__
  • 之类的东西

摘自__slots__文档:

  

SimpleNamespace可能可以代替SimpleNamespace。但是,对于结构化记录类型,请使用class NS: pass

由于应该使用namedtuple()来代替@dataclass的许多用例,因此应使用namedtuple而不是@dataclass来完成命名记录/结构。

您可能还想看看this PyCon talk by Raymond Hettinger,他进入SimpleNamespace的背景故事中并得到了使用。

答案 1 :(得分:4)

简短的答案是PEP 557涵盖了所有内容。让您的问题稍微有些混乱...

为什么?

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

如何选择何时使用它们?

PEP非常清楚,它们不是替代品,并且希望其他解决方案也能占有一席之地。

因此,与其他任何设计决策一样,您需要准确确定要关注的功能。如果其中包括以下内容,则您绝对不希望使用数据类。

  

在哪里不合适使用数据类?

     

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

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

SimpleNameSpace的现有定义如下:

  

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

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

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

那么,很显然,如果您关心顺序或不变性(或需要利基哈希控制),则应该使用数据类。

其他用例?

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