Python has a pretty printer (pprint(...)
). I would like to make my classes pretty printable. Will pretty print print my instances in a better way, if I provide a certain interface?
The Python documentation in section 8.11 shows different examples, but no example how to make a user defined class pretty printable.
So what interface need my classes to provide?
Is there any other (maybe better) formatter?
Use Case:
I want to pretty print the content of ConfigParser, for which I have create an extended version called ExtendenConfigParser. So I have the possibility to add more functionality or add a matching pretty print interface.
pprint
does not look for any hooks. The pprint.PrettyPrinter
uses a dispatch pattern instead; a series of methods on the class that are keyed on class.__repr__
references.
You can subclass pprint.PrettyPrinter
to teach it about your class:
class YourPrettyPrinter(pprint.PrettyPrinter):
_dispatch = pprint.PrettyPrinter._dispatch.copy()
def _pprint_yourtype(self, object, stream, indent, allowance, context, level):
stream.write('YourType(')
self._format(object.foo, stream, indent, allowance + 1,
context, level)
self._format(object.bar, stream, indent, allowance + 1,
context, level)
stream.write(')')
_dispatch[YourType.__repr__] = _pprint_yourtype
then use the class directly to pretty print data containing YourType
instances. Note that this is contingent on the type having their own custom __repr__
method!
You can also plug functions directly into the PrettyPrinter._dispatch
dictionary; self
is passed in explicitly. This is probably the better option for a 3rd-party library:
from pprint import PrettyPrinter
if isinstance(getattr(PrettyPrinter, '_dispatch'), dict):
# assume the dispatch table method still works
def pprint_ExtendedConfigParser(printer, object, stream, indent, allowance, context, level):
# pretty print it!
PrettyPrinter._dispactch[ExtendedConfigParser.__repr__] = pprint_ExtendedConfigParser
See the pprint
module source code for how the other dispatch methods are written.
As always, single-underscore names like _dispatch
are internal implementation details that can be altered in a future version. However, it is the best option you have here. The dispatch table was added in Python 3.5 and is present in at least Python 3.5 - 3.9 alpha.
You may want to look at rich
, a third-party library that has some great pretty-printing capabilities, and supports hooks (__rich_repr__
); see the documentation on customising pretty-printing.