If you're going to go to all that effort, you might as well superclass pprint
to accept a hook, then you'll only have to write all that code once.
It will also work better in cases where your class is defined after you've instantiated a pprint helper with pp = pprint.PrettyPrinter(indent=4).pprint
(a bad habit of mine).
Then you can opt-in with any class by using one of these methods [pun not intended]
[edit]: after some self-use, I realised a much easier alternate solution,
__pprint_repr__
. Rather than attempt to create your own pprint function,
simply define the __pprint_repr__
method and return a standard python object.
You can group multiple objects inside a dict
if you have a complex class.
[edit #2]: I also realised that that it can be useful to have all the _format variables passed to the __pprint_repr__
function, because that allows you to do really cool things -- like show a compacted output if your item is in a list (indent > 0) vs a full output if it's the only object (indent == 0)
This also means this solution is compatibled with Python 2.7, not just Python ~> 3.3
class my_object(object):
# produce pprint compatible object, easy as pie!
def __pprint_repr__(self, **kwargs):
return self.__dict__
# make a multi-level object, easy as cheese-cake!
def __pprint_repr__(self, **kwargs):
_indent = kwargs['indent']
if _indent:
return self._toText()
return { self._toText(): self.__dict__ }
# to take total control (python 3) (requires __repr__ be defined)
def __pprint__(self, object, stream, indent, allowance, context, level):
stream.write('my_object(\n')
self._format(object._data, stream, indent, allowance + 1, context, level)
stream.write(')')
pass
The sub-classing is simplicity itself -- tested in Python 3.7 and 2.7:
if _pprint_repr:
return PrettyPrinter._format(self, _pprint_repr(object, stream=stream,
indent=indent, allowance=allowance, context=context, level=level),
stream, indent, allowance, context, level)
# else check for alternate _pprint method (if supported ~ python 3.3)
if getattr(PrettyPrinter, '_dispatch', None):
_repr = type(object).__repr__
_pprint = getattr(type(object), '__pprint__', None)
_exists = self._dispatch.get(_repr, None)
if not _exists and _pprint:
self._dispatch[_repr] = _pprint
return PrettyPrinter._format(self, object, stream, indent, allowance, context, level)
pprint(config)
gives only<lib.ExtendedConfigParser.ExtendedConfigParser object at 0x0000000003569940>
. The internal data structures are two nested ordered dictionaries. I would like to print them as 2 nested dicts. I could write a function for this job, but I would like to have a method and/or pprint compatible class. – Extravehicularpprint
offers that functionality. However, you could give your class a__format__
method (in addition to__repr__
and__str__
methods) to make it print prettily when it's passed to theformat
built-in function or thestr.format
method. – Ignazio