【发布时间】:2020-04-16 07:35:52
【问题描述】:
我想知道除了None 字段之外,如何将嵌套数据类转换为字典。我知道asdict() 方法的存在,但我正在尝试编写类似于asdict() 的方法,该方法将在dict 创建期间忽略空值。
例如:
@dataclass
class Nested:
name: str = None
contacts: list = field(default_factory = list)
@dataclass
class Main:
nested: Nested = field(default_factory = Nested)
surname: str = None
预期结果是:
example = Main()
example_d = asdict(example)
print(example_d)
{"nested": {"contacts": []}}
我目前拥有的:
example = Main()
example_d = asdict(example)
print(example_d)
{"nested": {"name": None, "contacts": []}, surname: None}
我知道asdict() 会忽略没有值的字段并将默认值作为默认值,但在数据类初始化期间我需要= None。
我最终覆盖了 asdict() 和 _asdict_inner() 方法:
def asdict(obj, *, dict_factory=dict):
if not _is_dataclass_instance(obj):
raise TypeError("asdict() should be called on dataclass instances")
return _asdict_inner(obj, dict_factory)
def _asdict_inner(obj, dict_factory):
if _is_dataclass_instance(obj):
result = []
for f in fields(obj):
value = _asdict_inner(getattr(obj, f.name), dict_factory)
result.append((f.name, value))
return dict_factory(result)
elif isinstance(obj, tuple) and hasattr(obj, '_fields'):
return type(obj)(*[_asdict_inner(v, dict_factory) for v in obj])
elif isinstance(obj, (list, tuple)):
return type(obj)(_asdict_inner(v, dict_factory) for v in obj)
elif isinstance(obj, dict):
return type(obj)((_asdict_inner(k, dict_factory),
_asdict_inner(v, dict_factory))
for k, v in obj.items() if v is not None) # <- Mine change to exclude None values and keys.
else:
return copy.deepcopy(obj)
但它并没有按预期工作。
根据要求实施_is_dataclass_instance。它来自dataclass 模块。
def _is_dataclass_instance(obj):
"""Returns True if obj is an instance of a dataclass."""
return not isinstance(obj, type) and hasattr(obj, _FIELDS)
【问题讨论】: