Customizing pprint.PrettyPrinter
The documentation for the pprint
module mentions that the method PrettyPrinter.format
is intended to make it possible to customize formatting.
I gather that it's possible to override this method in a subclass, but this doesn't seem to provide a way to have the base class methods apply line wrapping and indentation.
- Am I missing something here?
- Is there a better way to do this (e.g. another module)?
Alternatives?
I've checked out the pretty
module, which looks interesting, but doesn't seem to provide a way to customize formatting of classes from other modules without modifying those modules.
I think what I'm looking for is something that would allow me to provide a mapping of types (or maybe functions) that identify types to routines that process a node. The routines that process a node would take a node and return the string representation it, along with a list of child nodes. And so on.
Why I’m looking into pretty-printing
My end goal is to compactly print custom-formatted sections of a DocBook-formatted xml.etree.ElementTree
.
(I was surprised to not find more Python support for DocBook. Maybe I missed something there.)
I built some basic functionality into a client called xmlearn that uses lxml. For example, to dump a Docbook file, you could:
xmlearn -i docbook_file.xml dump -f docbook -r book
It's pretty half-ass, but it got me the info I was looking for.
xmlearn has other features too, like the ability to build a graph image and do dumps showing the relationships between tags in an XML document. These are pretty much totally unrelated to this question.
You can also perform a dump to an arbitrary depth, or specify an XPath as a set of starting points. The XPath stuff sort of obsoleted the docbook-specific format, so that isn't really well-developed.
This still isn't really an answer for the question. I'm still hoping that there's a readily customizable pretty printer out there somewhere.
Consider using the
pretty
module:If you would like to modify the default pretty printer without subclassing, you can use the internal
_dispatch
table on thepprint.PrettyPrinter
class. You can see how examples of how dispatching is added for internal types like dictionaries and lists in the source.Here is how I added a custom pretty printer for MatchPy's Operation type:
Now if I use
pprint.pprint
on any object that has the same__repr__
asmatchpy.Operation
, it will use this method to pretty print it. This works on subclasses as well, as long as they don't override the__repr__
, which makes some sense! If you have the same__repr__
you have the same pretty printing behavior.Here is an example of the pretty printing some MatchPy operations now:
This question may be a duplicate of:
Using
pprint.PrettyPrinter
I looked through the source of pprint. It seems to suggest that, in order to enhance
pprint()
, you’d need to:PrettyPrinter
_format()
issubclass()
,_format()
Alternative
I think a better approach would be just to have your own
pprint()
, which defers topprint.pformat
when it doesn't know what's up.For example:
The big upside here is that you don't depend on
pprint
internals. It’s explicit and concise.The downside is that you’ll have to take care of indentation manually.
My solution was to replace pprint.PrettyPrinter with a simple wrapper that formats any floats it finds before calling the original printer.