3 ms·
I had this exact problem in Python and wanted to be able to use dot-notation (i.e "book.metadata.title") to query the structure (like MongoDB, etc do) so built
by ig1 12y ago
I had this exact problem in Python and wanted to be able to use dot-notation (i.e "book.metadata.title") to query the structure (like MongoDB, etc do) so built my own library for doing it:
https://github.com/imranghory/pson https://github.com/imranghory/pson
(Also available from pypi via "pip install pson")
- icebraining 12y agoclass MyDict(object): def __init__(self, d): self.__dict__.extend(d) def __repr__(self): return repr(self.__dict__) import json r = json.loads('{"body": {"translations": [{"tr...', object_hook=MyDict) >>> r.header.title u'Hello World' >>> r.body.translations[1] {u'translation': u'guten tag', u'language': u'german'} >>> map(attrgetter('language'), r.body.translations) [u'french', u'german']
- ig1 12y agoThe code in the library is actually pretty simple, but deals with many practical edge-cases (stepping into an array, handling missing values gracefully, etc.) that the above code doesn't. My longer term intention is adding other useful json manipulation and search functions to the library.
- icebraining 12y agoYeah. I just don't like putting syntax in a string; I'd rather use Python itself. By the way, you should remove the pprint import from the library, since you don't use it :)
- ig1 12y agoI considered that approach but found the JSON returned by some third-party apis contained characters in keys (dashes, spaces, etc) which have special meanings in python so can't be used natively.
- mjs7231 12y agoInteresting, I thought I was a rare breed using the following function quite a bit in my code. However, it seems these things are a dime a dozen. -- I modeled this one after the way Django does it. I think the only thing it does that yours doesn't is all a function if one of the dict values is an object. Thats useful for get_somevalue() type things on a tree of objects. def rget(obj, attrstr, default=None, delim='.'): try: parts = attrstr.split(delim, 1) attr = parts[0] attrstr = parts[1] if len(parts) == 2 else None if isinstance(obj, dict): value = obj[attr] elif isinstance(obj, list): value = obj[int(attr)] elif isinstance(obj, tuple): value = obj[int(attr)] elif isinstance(obj, object): value = getattr(obj, attr) if attrstr: return rget(value, attrstr, default, delim) return value except: return default
- j-kidd 12y agoThe jmespath library from boto is quite similar to this, and possibly has way more traction. Some differences: - jmespath uses `body.translations[0].language` instead of `body.translations.0.language`, and it can also do `body.translations[].language`. - jmespath doesn't support the "missing" use case