Dataclass是Python3.7新增的对象类型,如果你还没有使用Python3.7——这是最新发布的Python版本,请尽快到官方网站下载安装,一边随本文一起体会它的新发展。

简介

Dataclass是Python的类,但适合存储数据对象。数据对象是什么?下面列出这种对象类型的几项特征,虽然不全面:

  • 它们存储数据并表示某种数据类型,例如:数字。对于熟悉ORM的朋友来说(如果不熟悉,请参阅《跟老齐学Python:Django实战》中的讲述),数据模型实例就是一个数据对象。它代表了一种特定的实体。它所具有的属性定义或表示了该实体。
  • 它们可以与同一类型的其他对象进行比较。例如:大于、小于或等于。

当然还有更多的特性,但是这里列出的足以帮助你理解“数据对象”关键所在。

为了理解Dataclass类,我们将写一个简单的类,它包含一个数字,并且允许我们执行上面提到的操作。

Python 3.7提供了一个装饰器dataclass,用它可以将一个类转换为“数据对象”的类,即dataclass。

from dataclasses import dataclass

@dataclass
class A:
    pass

 下面,对这种类型进行深入研究。

初始化

下面创建一个类,注意初始化方法,主要是实现以该对象属性存储数字。

>>> class Number:
...     def __init__(self, val):
...         self.val = val
...
>>> one = Number(1)
>>> one.val
1

下面使用@dataclass装饰器实现以上同样的功能:

>>> @dataclass
... class Number:
...     val:int
...
>>> done = Number(1)
>>> done.val
1

归纳使用dataclass装饰器带来的变化:

1.不需要在__init__方法中给实例self的属性赋值。

2.有了类型提示,提高了可读性。现在我们立即知道属性val是整数型的——似乎在吸收强类型语言的特征。

如果还记得《Python之禅》中说过的“Readability counts”(重在可读性),似乎感觉上面的做法吻合了这种要求。

还可以这样写,设置默认值。

>>> @dataclass
... class Number:
...     val:int = 0
...
>>> do = Number()
>>> do.val
0
>>> dt = Number(2)
>>> dt.val
2

对象说明的表示方式

对象说明应该是用有意义的字符串表示的,它在在程序调试中非常有用。

默认的Python对象表示法不是很有意义:

>>> class Number:
...     def __init__(self, val=0):
...         self.val = val
...
>>> a = Number()
>>> a
<__main__.Number object at 0x10279bf60>

返回值没有用有意义的字符串表示,我们仅仅能够知道它在内存中的地址。

所以,如果你要自定义对象类型,最好要使用__repr__方法,它是一个对解释器友好的方法(详见《跟老齐学Python:轻松入门》中的有关阐述),通过这个方法可以对此对象给予有意义的说明。

>>> class Number:
...     def __init__(self, val=0):
...         self.val = val
...     def __repr__(self):
...         return "your object is: " + str(self.val)
...
>>> a = Number()
>>> a
your object is: 0

再来看调试结果,则告诉我们,变量a引用的对象就是数字1——我们得到一个有意义的对象说明:

如果不用上面的方式,而是使用@dataclass装饰器定义一个Dataclass类型的对象,则会自动添加一个__repr__函数,这样我们就不必手动实现它。

>>> @dataclass
... class Number:
...     val:int = 0
...
>>> a = Number()
>>> a
Number(val=0)

(未完,待续)

参考资料:

  • https://medium.com/mindorks/understanding-python-dataclasses-part-1-c3ccd4355c34
  • https://docs.python.org/3/library/dataclasses.html