Skip to content

Instantly share code, notes, and snippets.

@Nikasa1889
Created August 19, 2018 00:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Nikasa1889/14167980dea001beaa261f7522c192c4 to your computer and use it in GitHub Desktop.
Save Nikasa1889/14167980dea001beaa261f7522c192c4 to your computer and use it in GitHub Desktop.
import attr
from datetime import datetime
from attr import fields
@attr.s(slots=True)
class Small:
a = attr.ib(type=float, metadata={'JSON':'A'})
@attr.s(slots=True)
class TestField:
a = attr.ib(type=int, metadata={'JSON':'A'})
b = attr.ib(type=datetime, metadata={"JSON":"B"})
c = attr.ib(type=str, metadata={'JSON':'C'})
d = attr.ib(type=Small, metadata={'JSON':'D'})
x = TestField(1,datetime.now(),"123",Small(1))
attr.asdict(x)
def fromJSON(dikt, cls):
attrs = fields(cls)
vals = {}
for a in attrs:
jname = a.metadata['JSON']
v = dikt[jname]
if attr.has(a.type):
vals[a.name] = fromJSON(v, a.type)
elif a.type in (tuple, list, set):
# Get child type
mem_type = a.metadata['MemType']
vals[a.name] =[ fromJSON(i, globals()[mem_type]) for i in v]
elif a.type == datetime:
vals[a.name] = datetime.now()
else:
vals[a.name] = v
return cls(**vals)
def asJSON(inst, recurse=True, filter=None, dict_factory=dict,
retain_collection_types=False):
attrs = fields(inst.__class__)
rv = dict_factory()
for a in attrs:
v = getattr(inst, a.name)
jname = a.metadata['JSON']
if jname is None: continue
if filter is not None and not filter(a, v):
continue
if recurse is True:
if attr.has(v.__class__):
rv[jname] = asJSON(v, recurse=True, filter=filter,
dict_factory=dict_factory)
elif isinstance(v, (tuple, list, set)):
cf = v.__class__ if retain_collection_types is True else list
rv[jname] = cf([
asJSON(i, recurse=True, filter=filter,
dict_factory=dict_factory)
if attr.has(i.__class__) else i
for i in v
])
elif isinstance(v, datetime):
rv[jname] = str(v)
elif isinstance(v, dict):
df = dict_factory
rv[jname] = df((
asJSON(kk, dict_factory=df) if attr.has(kk.__class__) else kk,
asJSON(vv, dict_factory=df) if attr.has(vv.__class__) else vv)
for kk, vv in v.iteritems())
else:
rv[jname] = v
else:
rv[jname] = v
return rv
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment