从 Dict 转到 Dataclass

从 dataclass 转到 dict 可以用 asdict 函数 , 反向转换的时候 就比较困难. 不用外部的包的情况下, 提供一种思路.

def mask(v, d): #v 是 dict 数据, d 是 @dataclass 类型
      if isinstance(v, d): 
            pass 
      elif isinstance(v, Dict): 
            x = [v.get(k, None) for k in [i for i in d.__dict__['__annotations__']]] 
            y = list(d.__init__.__defaults__) 
            if len(y) > 0: 
                  n = len(x) 
                  m = len(y) 
                  for i in range(m): 
                        if x[n-m+i] is None: 
                              x[n-m+i] = y[i] 
            x = tuple(x) 
            v = d(*x) 
      else: 
            v = None 
      return v 

以上是转换用的函数, 用于处理 输入参数为dict形式

from dataclasses import dataclass, asdict
from typing import Dict 
def mask(v, d): #v 是 dict 数据, d 是 @dataclass 类型
      if isinstance(v, d): 
            pass 
      elif isinstance(v, Dict): 
            x = [v.get(k, None) for k in [i for i in d.__dict__['__annotations__']]] 
            y = list(d.__init__.__defaults__) 
            if len(y) > 0: 
                  n = len(x) 
                  m = len(y) 
                  for i in range(m): 
                        if x[n-m+i] is None: 
                              x[n-m+i] = y[i] 
            x = tuple(x) 
            v = d(*x) 
      else: 
            v = None 
      return v 
@dataclass 
class ddd: 
      a: str 
      c: str = "" 
      b: str = "" 
@dataclass 
class bbb: 
      a: str 
      b: ddd = None 
      c: str = "" 
      def __post_init__(self): 
            self.b=mask(self.b,ddd) 
@dataclass 
class aaa: 
      a: str 
      b: str 
      c: bbb = None 
      def __post_init__(self): 
            self.c=mask(self.c, bbb) 
if __name__=="__main__": 
      x = aaa(1, 2, {'a': 4, 'b': {'a':6,'c':7}}) 
      y = asdict(x) print(mask(y,aaa)) 

结果是 :
aaa(a=1, b=2, c=bbb(a=4, b=ddd(a=6, c=7, b=''), c=''))

posted @ 2020-12-08 15:34  方头狮  阅读(1169)  评论(1)    收藏  举报