Page cover

Dataclasses

Create dataclass

from dataclasses import dataclass

@dataclass
class Position:
    name: str
    lon: float
    lat: float

可以发现,主要起作用的是装饰符@dataclass ,需要注意,如果想要使用dataclass,需要Python 3.7或更高版本 使用dataclass的好处是可以节省书写__init()__等一些常用的实例方法

这里创建一个Position类,用来显示一个地点的位置

  • name:地点的名字

  • lon:经度

  • lat:纬度

新建一个实例来看看:

>>> pos = Position('Oslo', 10.8, 59.9)
>>> print(pos)
Position(name='Oslo', lon=10.8, lat=59.9)
>>> pos.lat
59.9
>>> print(f'{pos.name} is at {pos.lat}°N, {pos.lon}°E')
Oslo is at 59.9°N, 10.8°E

# 除了这种方法,还要一种类似创建namedtuple的方式也可以:

from dataclasses import make_dataclass
Position = make_dataclass('Position', ['name', 'lat', 'lon'])

Default Value

Input hint

大家可以发现我们的Positon类规定了三个属性的类型:

  • name:str

  • lon:float

  • lat:float

现在如果想要开放限制,允许任意的数据类型,可以这么做:

Add a method

More flexible use

目前为止我们已经看到了dataclass的基础用法,现在我们看看根据实际需要,有哪些其他灵活的应用方式。

现在创建两个类,纸牌类和牌库类,纸牌类的属性包括花色和数字,牌库是List类型,包含纸牌类的一些实例:

现在我们可以创建一套完整的扑克牌牌库,注意这里使用了符号表示花色,建议在实际环境中改换为字符串:

理论上,我们可以把这个方法作为Deck类的初始变量,但是根本不行,因为它可变:

Field

现在简单总结一下dataclass中使用field涉及到的关键参数:

  • default: Default value of the field

  • default_factory: Function that returns the initial value of the field

  • init: Use field in .__init__() method? (Default is True.)

  • repr: Use field in repr of the object? (Default is True.)

  • compare: Include the field in comparisons? (Default is True.)

  • hash: Include the field when calculating hash()? (Default is to use the same as for compare.)

  • metadata: A mapping with information about the field

最后这个metadata有点像前端h5中的那个,就是可以为类的一个属性添加一个额外的描述信息:

__str__,__repr__

Frozen-dataclass

Inheritance

使用dataclass的继承也比较简单,和普通类的继承没有太大区别:

这里可以发现,创建Capital类的实例时会自动继承了父类的属性,我们只需要额外加入country这个新属性就可以了

假如父类初始化时有默认值:

Optimization

可以用我之前提到的slot方法进行优化:

Last updated

Was this helpful?