Skip to content

Instantly share code, notes, and snippets.

@hxer
Last active November 1, 2022 08:02
Show Gist options
  • Save hxer/8119b017d9492c72a6d6978e58a0b71e to your computer and use it in GitHub Desktop.
Save hxer/8119b017d9492c72a6d6978e58a0b71e to your computer and use it in GitHub Desktop.

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())