0

tldr; I'm trying to use __repr__() and pprint() to pretty-print a custom python class to the terminal, but the output width remains the same no matter what width I pass to pprint(). I have seen the question How can I make my class pretty printable in Python? - Stack Overflow, but it doesn't explain why the width isn't changing in my case, even though pprint() successfully prints my custom class.

Here's my __repr__() function.

def __repr__(self):
    output = 'task(' + repr(self.name) + ', ' + repr(self.subtasks) + ')'
    return output

And here's the problem: when I try to test pprint() with the following loop,

for width in [ 80, 20, 5 ]:
    print('WIDTH =', width)
    pprint(task_tree, width=width)

all outputs have the same width.

WIDTH = 80
task(root, [task(Top Level 1, [task(secondary, []), task(secondary b, []), task(secondary c, [])]), task(Top Level 2, []), task(Top Level 3, [])])
WIDTH = 20
task(root, [task(Top Level 1, [task(secondary, []), task(secondary b, []), task(secondary c, [])]), task(Top Level 2, []), task(Top Level 3, [])])
WIDTH = 5
task(root, [task(Top Level 1, [task(secondary, []), task(secondary b, []), task(secondary c, [])]), task(Top Level 2, []), task(Top Level 3, [])])

What could be going wrong? How should I modify my class' __repr__() so that this works as expected, i.e. that pprint() prints representations of the class with widths of 80, 20, and 5 characters?


I based my approach on the following excerpt from pprint — Pretty-Print Data Structures — PyMOTW 3, where it's demonstrated how to use pprint() with arbitrary classes.

Arbitrary Classes

The PrettyPrinter class used by pprint() can also work with custom classes, if they define a __repr__() method.

pprint_arbitrary_object.py

from pprint import pprint


class node:

    def __init__(self, name, contents=[]):
        self.name = name
        self.contents = contents[:]

    def __repr__(self):
        return (
            'node(' + repr(self.name) + ', ' +
            repr(self.contents) + ')'
        )


trees = [
    node('node-1'),
    node('node-2', [node('node-2-1')]),
    node('node-3', [node('node-3-1')]),
]
pprint(trees)

The representations of the nested objects are combined by the PrettyPrinter to return the full string representation.

$ python3 pprint_arbitrary_object.py

[node('node-1', []),
 node('node-2', [node('node-2-1', [])]),
 node('node-3', [node('node-3-1', [])])]
David
  • 606
  • 9
  • 19
  • Didn't you ask the same question earlier? – Barmar Mar 16 '21 at 20:53
  • yes, but I made enough edits that I thought I should delete the original and create a new question. – David Mar 16 '21 at 20:58
  • You should edit the original and request that it be reopened. – Barmar Mar 16 '21 at 21:01
  • I'm working from memory, but I don't see any significant differences. – Barmar Mar 16 '21 at 21:02
  • I don't think the pretty printer will break the representation of a single object across multiple lines. – Barmar Mar 16 '21 at 21:04
  • 1
    Since your `__repr__` method combines all the subtasks into a single representation string, the pretty printer doesn't know anything about the nesting sdtructure. – Barmar Mar 16 '21 at 21:05
  • I changed the order of my explanation, made reference to another SO question, and edited the passage from PMOTW to reference the python 3 pmotw instead of python 2. Should I edit and undelete the original? – David Mar 16 '21 at 21:06
  • Too late now, remember it for the future. – Barmar Mar 16 '21 at 21:07
  • ok will do thank you. – David Mar 16 '21 at 21:07
  • The example you show doesn't have it splitting up the `node` objects, it's just collecting them into a list and pretty-printing the list. – Barmar Mar 16 '21 at 21:09
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/229998/discussion-between-david-and-barmar). – David Mar 16 '21 at 21:10
  • I have tried splitting up the node objects individually with `subtasks = ''.join([repr(s) for s in self.subtasks])`, and then setting output with `output = 'task(' + repr(self.name) + ', ' + subtasks + ')'`, but it still doesn't change the width. – David Mar 16 '21 at 21:21
  • That's still a single string when you join it. – Barmar Mar 16 '21 at 22:50
  • `pprint()` doesn't know that the string was constructed by combining multiple objects. It's just a string when `repr()` returns it. – Barmar Mar 16 '21 at 22:51
  • I closed the last question as a duplicate, but for some reason you say the solutions there won't work for you. Did you try the first answer of adding to the `_dispatch` table? – Barmar Mar 16 '21 at 22:53
  • If none of them work, then I don't think there's a solution. `pprint()` isn't really designed to be extensible to custom aggregate objects. – Barmar Mar 16 '21 at 22:54

0 Answers0