Pretty print Python dict

Viewed 1210

I'm used to use the pprint module to pretty print my built-in Python container objects such as dict and list. However when printing, I'm faced with the difficulty of forcing the containers to use the __str__ on the contained objects (since by default they use the __repr__ method on the contained objects), whilst maintaining the pretty printing.

Here is an example:

import pprint

class H:
    """ Example of a contained object
    """
    def __str__(self):
        return "This is my H class string representation"

    def __repr__(self):
        return "H()"

d = {
    'a': H(),
    'b': {
        'c': H(),
        'd': H()
    }
}

pprint.pprint(d, width=10)

returns d pretty printed:

{'a': H(),
 'b': {'c': H(),
       'd': H()}}

But as you can see the __repr__ is called on the H objects.

To force the dict to use the __str__ on the contained objects, some people suggested using join(). Something like:

print("{" + "\n".join("{!r}: {!s},".format(k, v) for k, v in d.items()) + "}")

which returns:

{'a': This is my H class string representation,
'b': {'c': H(), 'd': H()},}

And obviously won't work on nested dictionaries, and also there's no way to use pprint in that case since after the join we end up with a string.

Ideally what I would like to have printed is:

{'a': This is my H class string representation,
 'b': {'c': This is my H class string representation,
       'd': This is my H class string representation}}

For context, the keys of my dictionaries are always strings, and the values are the objects in question such as H(), of whom I need the __str__ represenation and not the __repr__.

1 Answers

Python allow to dynamically change methods in classes. So you could just temporarily have __repr__ be __str__:

def str_pprint(d):
    sv = H.__repr__
    H.__repr__ = H.__str__
    pprint.pprint(d, width=10)
    H.__repr__ = sv

str_pprint(d)

With your data, it gives as expected:

{'a': This is my H class string representation,
 'b': {'c': This is my H class string representation,
       'd': This is my H class string representation}}

But beware: this changes globally the class attributes, so this cannot be used if multiple execution threads (multithreaded programs or interuption handlers) are expected.

Related