[Python-ideas] REG: Scope of a better API for JSON parser

Andrew Barnert abarnert at yahoo.com
Sun Apr 6 12:33:48 CEST 2014


From: Anoop Thomas Mathew <atmb4u at gmail.com>
Sent: Sunday, April 6, 2014 2:55 AM


>On 6 April 2014 10:56, Andrew Barnert <abarnert at yahoo.com>wrote:
>
>From: Anoop Thomas Mathew <atmb4u at gmail.com>


[snip]

>>>json_doc.get(["account details", "account balance"])

>>>1000000000.00
>>
>>sample_json['account details']['account balance']
>>
>I completely agree to your point. But what if the document is of something like this:
>
>person['country']['state']['city']['county']


So what? Do you not understand that? It's simple, explicit, readable, and identical to code you could write in other languages like JavaScript, Ruby, etc. This is a familiar, easily-recognizable pattern from code dealing with complex heterogeneous objects in all of these languages. Do you really want to do away with that for the sake of saving a few keystrokes?

[snip]

>>I'm going to assume that the whole bit about parsing is a red herring, and the part you actually want is the ability to call the "get" function with multiple keys and recursively walk the structure. I'm sure you can find recipes for that on ActiveState or PyPI, but it's also very trivial to write yourself:

>> 
>>    def get(obj, *keys, default=None):
>>        for key in keys:
>>            try:
>>                obj = obj[key]
>>            except LookupError:
>>                return default
>>        return obj
>
>I apologize for making the previous mail complicated. You have pinned down what I was suggesting.
>
>My suggestion is to integrate something similar as you suggested above to the cpython json module.


Again: Why would you put it in the json module? You don't have any JSON anything anywhere; you have a dict with dicts inside it. If you want a simple function that works on any indexable object full of indexable objects, that function will work the same way whether you give it something you parsed from a JSON string you pulled off the wire, something you built up yourself out of database queries, a multi-dimensional array, a tree, etc.

>Won't that be a good feature for developers to be able to write code without worrying if it going to fail and writing may try.. except or if else to handle those edge cases? 

No, because Python already has features for that.

First, you don't need many try/excepts, just a single one, no matter how many possibly-raising lookups you're doing:

    >>> try:

    ...     val = d['stuff']['things'][7]
    ... except LookupError:
    ...     val = None

It doesn't matter whether d['stuff'] was missing, or d['stuff']['things'], or d['stuff']['things'][7]; they'll all be handled by a single try.

And if you don't want to worry about try/except (or if/else, but you really shouldn't ever be using if/else for cases like this), dict already has a get method:

    >>> d = {'a': 1, 'b': 2}

    >>> d['c']
    KeyError: 'c'

    >>> d.get('c')
    None
    >>> d.get('c', 0)
    0

Also, different projects are likely to need different variations on the same theme. Sometimes you want a Cocoa-KV-style dotted string of keys, or a Windows-registry-style slashed string, instead of an iterable. Sometimes you only want to handle recursive mappings or recursive sequences, sometimes recursive mappings-and-sequences. Sometimes you want to return a default value other than None, maybe even one that's dependent on where the lookup failed. Sometimes you want to look up multiple key-paths at once ala operator.itemgetter. And so on. All of these are dead-simple to write yourself, so any project that needs some version of this should just include the version that it needs.



More information about the Python-ideas mailing list