-
-
Save href/1319371 to your computer and use it in GitHub Desktop.
| from collections import namedtuple | |
| def convert(dictionary): | |
| return namedtuple('GenericDict', dictionary.keys())(**dictionary) | |
| """ | |
| >>> d = dictionary(a=1, b='b', c=[3]) | |
| >>> named = convert(d) | |
| >>> named.a == d.a | |
| True | |
| >>> named.b == d.b | |
| True | |
| >>> named.c == d.c | |
| True | |
| """ |
I wrote up this [1] implementation a little while ago. Stumbled upon this thread. From the namedtuple_fmt module, the serialize function accepts a dictionary (e.g. from a json.load call) and will convert to an instance of the given namedtuple-deriving type. Likewise, deserialize will convert any namedtuple-deriving type into a dictionary-l object. These functions also work on any list-like type: List and Tuple are process-able.
E.g.
import json
from typing import Sequence
from namedtuple_fmt import serialize, deserialize
X = NamedTuple('X', [('msg',str)])
json_str="""{"msg": "This is the first message"}"""
first_msg = deserialize(json.loads(json_str), X)
print(first_msg.msg)
print(deserialize(serialize(first_msg)) == X("This is the first message"))
print(deserialize(json.loads(json.dumps(serialize(first_msg)))) == X("This is the first message"))
json_str="""[{"msg": "This is the first message"},{"msg": "This is the 2nd message"}]"""
messages = deserialize(json.loads(json_str), Sequence[X])
print(f"{len(messages)} messages")
print('\n'.join(map(lambda x: x.msg, messages))
Implementation note: There are explicit type checks for the Sequence types. It's important to not mess-up when it comes to handling str and tuple. A first draft of this idea incorrectly did for _ in X when trying to "test" if something was list-like. This idea, unfortunately, will iterate over characters in a str or elements in a tuple. We want the tuple-iterating part, but not when it comes to a NamedTuple (or namedtuple)!
[1] https://gist.github.com/malcolmgreaves/d71ae1f09075812e54d8ec54a5613616
Anyone interested in this should also check out the
dotmappackage / alternatives to that package