Python Dataclass调用fields函数为何输出默认值而非实例值?
你定义了如下CSVData数据类并设置了字段默认值:
from dataclasses import dataclass, fields from typing import Optional @dataclass class CSVData: SUPPLIER_AID: str = "" EAN: Optional[str] = None DESCRIPTION_SHORT: str = "" DESCRIPTION_LONG: str = "Article long description"
创建实例并传入部分字段值后,打印实例能正确显示实际值:
data = CSVData(SUPPLIER_AID='1234-568', EAN='EAN number', DESCRIPTION_SHORT='Article Name') print(data)
输出:CSVData(SUPPLIER_AID='1234-568', EAN='EAN number', DESCRIPTION_SHORT='Article Name', DESCRIPTION_LONG='Article long description')
但用fields()遍历字段并打印field.default时,得到的却是类定义的默认值:
for field in fields(data): print(field.default)
输出:"", None, "", Article long description
你期望输出实例的实际值:1234-568, EAN number, Article Name, Article long description,原因及解决方法如下:
核心原因
fields()函数返回的是类级别的字段元数据对象,这些对象存储的是类定义阶段的字段配置信息(比如默认值、类型注解等),和具体实例的属性值无关。field.default属性专门用来存储类里定义的字段默认值,不会随实例的属性变化而改变。
正确获取实例实际值的方法
要获取实例的实际属性值,需要通过实例本身访问,结合field.name用getattr()函数读取对应属性:
for field in fields(data): print(getattr(data, field.name))
执行后就能得到你期望的输出:1234-568, EAN number, Article Name, Article long description
批量获取实例字段与值的快捷方式
如果需要一次性获取实例所有字段及其对应值,可以使用dataclasses.asdict()方法将实例转换为字典:
from dataclasses import asdict print(asdict(data))
输出:{'SUPPLIER_AID': '1234-568', 'EAN': 'EAN number', 'DESCRIPTION_SHORT': 'Article Name', 'DESCRIPTION_LONG': 'Article long description'}
内容的提问来源于stack exchange,提问作者Attila Toth

