[python]数据类(dataclass)简介
创始人
2025-05-30 07:25:02
0

文章目录

    • 数据类定义
      • 装饰器
      • field
      • 初始化
      • 数据比较
      • 后处理
    • dataclasses方法

Python3.7引入了dataclass。dataclass装饰器可以声明Python类为数据类;数据类适合用来存储数据,一般而言它具有如下特征:

  • 数据类表示某种数据类型,数据对象代表一种特定类的实体,包含了实体的属性。
  • 同类型的对象之间可以进行比较;如,大于、小于或等于。

数据类定义

就其本质而言,数据类并没有什么特别之处,只是@dataclass装饰器自动生成__repr__,init,__eq__等一系列方法。定义数据类:

from dataclasses import dataclass@dataclass
class A:normal: strdefVal: int = 0

装饰器

dataclass完整形式为(True为生成对应方法,False将不生成;若类中已定义对应方法,则忽略此参数):
@dataclass(init=True, repr=True, eq=True, order=False, unsafe_hash=False, frozen=False)

  • init:默认将生成__init__方法;
  • repr:默认将生成__repr__方法;repr字符串包含类名、每个字段名称和其repr(按其类中定义顺序);
  • eq:默认将生成__eq__方法;如果传入False,那么__eq__方法将不会被dataclass添加,但会继承object.__eq__(比较id);
  • order:默认不生成__gt__、__ge__、__lt__、__le__方法;
  • unsafe_hash:如果是False(默认),则根据eq和frozen的设置方式生成__hash__()方法(由内置的hash()使用)。
    • 如果eq和frozen都为真,默认情况会生成一个__hash__()方法;
    • 如果eq为真而frozen为假,则__hash__()将被设置为 None,将其标记为不可散列(确实如此,因为它是可变的);
    • 如果eq为假,则__hash__()将保持不变,这意味着将使用超类的__hash__()方法(如果超类是object,将回退到基于id的散列)。
  • frozen:若为true,实例初始化后属性将无法修改;

field

通过field方法,可定制属性:
dataclasses.field(*, default=MISSING, default_factory=MISSING, repr=True, hash=None, init=True, compare=True, metadata=None)

  • default:如果提供,这将是该字段的默认值。
  • default_factory:用于指定具有可变默认值的字段,必须是一个无参可调用对象;与default互斥(不可同时指定)。
  • init:如果为true(默认值),则该字段作为参数包含在生成的__init__()方法中。
  • repr:如果为true(默认值),则该字段包含在生成的__repr__()方法返回的字符串中。
  • compare:如果为true(默认值),则该字段包含在生成的相等性和比较方法中(__eq__() , __gt__()等等)。
  • hash:可以是布尔值或None:
    • 为None(默认值),则使用compare的值,这通常是预期的行为(不鼓励将此值设置为None以外的任何值);
    • 为true,则此字段包含在生成的__hash__()方法中;
    • 设置hash=False但compare=True(即从hash中排除某个字段,但仍用于比较)的一个可能原因是,计算字段的hash代价很高;
  • metadata:这可以是映射或None;None被视为一个空的字典。这个值包含在MappingProxyType()中,使其成为只读,并暴露在Field对象上(是作为第三方扩展机制提供的)。

使用default_factory生成默认值:

from dataclasses import dataclass, field
import randomdef build_marks() -> list:return [random.randint(0, 1000) for i in range(5)]@dataclass(order=True)
class RandMark:marks: list = field(default_factory=build_marks)r = RandMark() # 使用build_marks生成默认值
print(r)

初始化

通过dataclass装饰器修饰后的类:

  • 无需定义__init__,dataclass会自动处理;
  • 以易读的方式预先定义成员属性(及类型提示);并可定义默认值;
  • dataclass会自动添加一个__repr__函数;

数据比较

通过@dataclass(order = True)可自动添加比较方法(__eq__和__lt__):

  • 比较是通过属性(字段)生成的元组,进行比较的;如上比较元组为(normal, defVale)

通过compare=False,可设定不用于比较的字段:

@dataclass(order=True)
class Student:name: str = field(compare=False)score: floats = [Student("mike", 90),Student("steven", 80),Student("orange", 70)]
print(sorted(s)) # 只根据score排序

后处理

通过__post_init__可做后处理(在__init__返回前,自动调用):

from dataclasses import dataclass@dataclass
class FloatNumber:val: floatdecimal: float = 0integer: float = 0def __post_init__(self):self.decimal, self.integer = math.modf(self.val)f = FloatNumber(1.2) # decimal与integer自动赋值

dataclasses方法

dataclasses内置属性与方法:

  • fields(class_or_instance):返回字段Field对象的元组;
  • asdict(instance, *, dict_factory=dict):将数据类转换为字典,(name:value)对;
  • astuple(instance, *, tuple_factory=tuple):将数据类转换为元组;
  • replace(instance, **changes):创建与instance相同类型的新对象,changes为要修改的值;

相关内容

热门资讯

央企名录更新中国长安汽车集团入... 新京报贝壳财经讯(记者王琳琳)7月29日,国务院国资委网站中央企业名录更新,中国长安汽车集团有限公司...
A股午评:三大指数分化,沪指跌... 格隆汇7月29日|A股主要指数涨跌不一,截至午间收盘,沪指跌0.08%报3595.19点,深成指跌0...
2025年基金二季报划重点!泓... 来源:新浪基金 2025年第二季度泓德睿享一年持有期混合A基金净值增长率为3.09%,同期业绩比较基...
美团发文:绝不自营,浣熊食堂只... 来源:猎云网 7月29日,美团官方公众号发文称,经过半年多的试运营,7月初正式推出“浣熊食堂”品牌以...
独角兽疫苗企业三冲港股IPO:... 疫苗行业独角兽三冲港股IPO了! 在国产疫苗行业持续升级转型的浪潮中,一家坚持技术创新的企业正蓄势待...
A股站上新台阶,看好科技非银接... |2025年7月28日 星期一| NO.1中信建投:A股站上新台阶,看好科技非银接力 中信建投研报表...
中国长安汽车集团挂牌成立,朱华... 7月29日上午,中国长安汽车集团有限公司(以下简称“中国长安”)在重庆挂牌成立。这既是国内第三家汽车...
原创 扒... 懂车帝一场测试,成了智驾领域的“照妖镜”。测试结果触目惊心,无一车型全优通过!那些被吹上天的“遥遥领...
2025年LNG船拆解创纪录,... 2025年,LNG运输船拆解市场迎来爆发式增长,待拆解船成交量创下纪录——这凸显出在现货费率低迷的背...
中国押注电力无限的未来 文|小卢鱼 编辑|杨旭然 中国第99家央企中国雅江集团横空出世,序列号22,位于中国长江三峡集团有限...
多地消协发布上半年消费者投诉情... 7月以来,多地消协陆续发布了2025年上半年消费者投诉情况,从受理情况来看,消费欺诈、虚假宣传、预付...
7.28纯碱日评:纯碱市场交投... 纯碱市场分析 今日国内纯碱市场整体呈现稳中震荡走势,价格跌多涨少。截至目前,华北地区轻质纯碱价格在1...
国家税务总局:我国税收的调节分... 7月28日,国务院新闻办公室举行高质量完成“十四五”规划系列主题新闻发布会,介绍“十四五”时期税收改...
7.29黄金首现四连阴 交易有两个悲剧,一是万念俱灰,另一则是踌躇满志,美丽属于自信者,从容属于有备者,单边属于布局者,这本...
“吃药”行情再爆发,药ETF上... 7月29日早盘,A股“吃药”行情再爆发,制药、医疗联袂拉涨。 国内首只跟踪制药指数的药ETF(562...
上海谊众:7月28日融券卖出2... 证券之星消息,7月28日,上海谊众(688091)融资买入1424.3万元,融资偿还9642.78万...
凌晨重磅,又创新高! 【导读】标普500指数和纳斯达克指数双双创新高,英伟达市值突破4.3万亿美元 见习记者 储是 美东时...
贬值!人民币中间价单日调降48... 北京商报讯(记者 廖蒙)7月28日,中国人民银行授权中国外汇交易中心公布,当日银行间外汇市场人民币汇...
ETF盘中资讯|“吃药”行情再... 7月29日早盘,A股“吃药”行情再爆发,制药、医疗联袂拉涨。 国内首只跟踪制药指数的药ETF(562...
拓山重工连续5涨停后现&quo... 7月29日,拓山重工股价出现剧烈波动。该股以涨停价开盘,延续此前连续涨停态势。开盘后不久,股价突然出...