Skip to content

Instantly share code, notes, and snippets.

@hxer
Last active November 1, 2022 08:02

Revisions

  1. hxer revised this gist Sep 21, 2020. No changes.
  2. hxer created this gist Sep 21, 2020.
    59 changes: 59 additions & 0 deletions dict_dataclass.py
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,59 @@
    import json
    from typing import Dict
    from dataclasses import (
    asdict, dataclass, field, fields, is_dataclass
    )


    # 对于一些嵌套的数据类,需要深度遍历
    class EnhancedJSONEncoder(json.JSONEncoder):
    def default(self, o):
    if is_dataclass(o):
    return asdict(o)
    return super().default(o)


    def dicts_to_dataclasses(instance):
    """将所有的数据类属性都转化到数据类中"""
    cls = type(instance)
    for f in fields(cls):
    if not is_dataclass(f.type):
    continue

    value = getattr(instance, f.name)
    if not isinstance(value, dict):
    continue

    new_value = f.type(**value)
    setattr(instance, f.name, new_value)


    @dataclass
    class Base:
    def __post_init__(self):
    dicts_to_dataclasses(self)

    def as_dict(self):
    return asdict(self)

    def as_json(self):
    return json.dumps(self, cls=EnhancedJSONEncoder)

    if __name__ == "__main__":
    @dataclass
    class Download(Base):
    url: str
    expire_time: int
    headers: Dict = field(default_factory=dict)

    download = {
    'url': 'http://example.com',
    'expire_time': 1,
    'headers': {
    'Content-Type': 'application/json'
    }
    }

    d = Download(**download)
    print(d.as_dict())
    print(d.as_json())