Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to print integers as hex strings using json.dumps() in Python

Currently I am using the following code to print a large data structure

print(json.dumps(data, indent=4))

I would like to see all the integers that get printed in hex instead of decimal. Is that possible? It seems that there is no way to override the existing encoder for integers. You can only provide a default for types not already handled by the JSONEncoder class, but no way to override how it encodes integers.

I figured out I can override the default integer printing behavior using sys.displayhook if I was running in the command line but I am not.

Just for reference the data structure is a mix bag of dicts, lists, strings, ints, etc. So that is why I went with the json.dumps(). The only other way I can think of doing it is to parse it myself and then I would be re-writing the json module.

Update: So I ended up implementing it with serializing functions that just print a copy of the original data structure with all integer types converted to hex strings:

def odprint(self, hexify=False):
    """pretty print the ordered dictionary"""
    def hexify_list(data):
        _data = []
        for i,v in enumerate(data):
            if isinstance(v, (int,long)):
                _data.insert(i,hex(v))
            elif isinstance(v,list):
                _data.insert(i, hexify_list(v))
            else:
                _data.insert(i, val)
        return _data

    def hexify_dict(data):
        _data = odict()
        for k,v in data.items():
            if isinstance(v, (dict,odict)):
                _data[k] = hexify_dict(v)
            elif isinstance(v, (int, long)):
                _data[k] = hex(v)
            elif isinstance(v,list):
                _data[k] = hexify_list(v)
            else:
                _data[k] = v
        return _data

    if hexify:
        print(json.dumps(hexify_dict(self), indent=4))
    else:
        print(json.dumps(self, indent=4))

Thanks for the help. I realize that I end up making an odict from a standard dict, but its just for printing so its fine for what I need.

like image 900
Plazgoth Avatar asked Feb 01 '12 17:02

Plazgoth


1 Answers

A possible approach is to have a serialize function, which produces a copy of your dictionary on the fly and uses the standard json module to dump the string. A preliminary implementation looks like:

import json

def serialize(data):
    _data = {}
    for k, v in data.items():
        if isinstance(v, int):
            _data[k] = hex(v)
        else:
            _data[k] = v
    return json.dumps(_data, indent=4)


if __name__ == "__main__":
    data = {"a":1, "b":2.0, "c":3}
    print serialize(data)

output:

{
    "a": "0x1", 
    "c": "0x3", 
    "b": 2.0
}

Notice that this preliminary implementation does not work with lists, but this is easily changed.

Some may claim that the approach is memory-intensive because it creates a copy of the original data. This may be the case, but if your data structure is that big, then maybe you should (a) not be using JSON, or (b) create a copy of the JSON module in your working directory and tailor it to your needs.

Cheers.

like image 53
Escualo Avatar answered Oct 01 '22 01:10

Escualo