Skip to content

Instantly share code, notes, and snippets.

@urigoren
Last active May 17, 2020 13:02
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 urigoren/78222d12eb53f76e6c6e3ad815873bb8 to your computer and use it in GitHub Desktop.
Save urigoren/78222d12eb53f76e6c6e3ad815873bb8 to your computer and use it in GitHub Desktop.
from collections import namedtuple
from datetime import datetime
date_pattern = "%Y-%m-%dT%H:%M:%S.%fZ"
Point = namedtuple("Point", ("x", "y"))
def serialize_datetime(nt):
assert hasattr(nt, '_asdict')
d = nt._asdict()
if "dt" not in d:
return nt
d["dt"] = datetime.strftime(d["dt"], date_pattern)
return type(nt)(**d)
def deserialize_datetime(d: dict):
assert isinstance(d, dict)
if "dt" not in d:
return d
d["dt"] = datetime.strptime(d["dt"], date_pattern)
return d
def from_dicts(lst, NamedTuple=None):
if len(lst) == 0:
return []
first = lst[0]
if NamedTuple is None:
if "_namedtuple" in first:
NamedTuple = locals()[first["_namedtuple"]]
lst = [{k: v for k, v in d.items() if k in NamedTuple._fields} for d in lst]
else:
raise TypeError("Missing `_namedtuple` field, Cannot infer the type of the list members.")
elif isinstance(NamedTuple, str):
# Autoload named tuple
NamedTuple = locals()[NamedTuple]
if isinstance(first, NamedTuple):
return lst
elif isinstance(first, dict):
return [NamedTuple(**deserialize_datetime(d)) for d in lst]
raise TypeError("Cannot cast '{s}' to '{t}'".format(s=type(first).__name__, t=NamedTuple.__name__))
def to_dicts(lst, with_type=True):
assert hasattr(lst, "__iter__"), "`lst` must be iterable"
assert all([hasattr(x, '_asdict') for x in lst]), "Not all members of the list are namedtuples"
if with_type:
return [dict(serialize_datetime(x)._asdict(), _namedtuple=type(x).__name__) for x in lst]
return [serialize_datetime(x)._asdict() for x in lst]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment