10

Standard pprint module is nice when deals with lists, dicts and so on. But sometimes completely unusable with custom classes:

  • The only way to make it print usable information about an object of some class is to override __repr__, but what if my class already have nice, eval()'able __repr__ which is not showing the information I want to see in pprint ouput?

  • Ok, I will write print-oriented __repr__, but in this case it is impossible to pretty-print something inside my class:

.

class Data:
    def __init__(self):
        self.d = {...}

I can't pretty-print self.d contents, I can return one-line representation only(at least without playing with stacktraces, etc). - Overriding PrettyPrinter is not an option, I dont want to do it every time I want to pretty-print the same class.

So... Is there any alternatives to pprint which allows to make a custom class pretty-printable?

Equidamoid
  • 1,447
  • 1
  • 13
  • 24
  • Found https://pypi.python.org/pypi/pretty/0.1 , but it seems to be py2.X only – Equidamoid May 19 '13 at 10:25
  • "I can return one-line representation only" -- why is this? NumPy for example returns multi-line repr()s that work just fine. Here's an example, as a Python string : `"array([(0, 0, (0, 0, 0)), (0, 0, (0, 0, 0)), (0, 0, (0, 0, 0)),\n (0, 0, (0, 0, 0))], \n dtype=[('foo', 'u1'), ('bar', ' – kampu May 19 '13 at 10:31
  • @kampu I meant I cant return multiline string because it will break `pprint` indentation. – Equidamoid May 19 '13 at 10:55
  • Yeah, I tried to edit and indicate I'd just realized that, but the 5min grace period on editing had run out. Good to know we're on the same page, anyway :) – kampu May 19 '13 at 10:58
  • @Equidamoid, if you need a Python 3 solution, please indicate it in your question, and add an appropriate tag. – utapyngo May 19 '13 at 15:12
  • And why is subclassing `PrettyPrinter` not an option? – utapyngo May 19 '13 at 15:25
  • And why is it impossible to pretty-print something inside your class in case of writing a custom `__repr__`? The string it returns can contain a representation of any field of your object. – utapyngo May 19 '13 at 15:29
  • @utapyngo done. Oops, the phrase about subclassing is incorrect a little bit %) I just don't want to add support for the particular class to `PrettyPrinter` (because class-specific code shouldn't be there), and looking for "generic" solution, such as the one mentioned in my 1st comment. – Equidamoid May 19 '13 at 15:43
  • @utapyngo it is impossible to generate proper multiline string in `__repr__` because of unknown current indentation level. – Equidamoid May 19 '13 at 21:23

4 Answers4

4

There is an improved and maintained Python 2.x/3.x port of "pretty" library in IPython: https://ipython.readthedocs.io/en/stable/api/generated/IPython.lib.pretty.html

snoob dogg
  • 2,491
  • 3
  • 31
  • 54
Mikhail Korobov
  • 21,908
  • 8
  • 73
  • 65
3

If the pretty module satisfies your needs, you can make it work with Python 3.

  1. Download and unpack the pretty.py file.
  2. Run 2to3 on it:

    python -m lib2to3 -w pretty.py
    
  3. Comment out the following lines:

    569: types.DictProxyType:        _dict_pprinter_factory('<dictproxy {', '}>'),
    580: xrange:                     _repr_pprint,
    
  4. Put the file near your script.

  5. Import it as usual:

    import pretty
    
utapyngo
  • 6,946
  • 3
  • 44
  • 65
1

for pretty printing you may be looking for __str__ instead of (or as well as) __repr__

e.g.

>>> import datetime
>>> now = datetime.datetime.now()
>>> print now
2013-05-19 13:00:34.085383
>>> print repr(now)
datetime.datetime(2013, 5, 19, 13, 0, 34, 85383)
second
  • 28,029
  • 7
  • 75
  • 76
  • Now imagine that instead of datetime you have a class with several `dict`s big enough so they don't fit into one terminal row. And then you have a `dict` with several those objects... That's my case. – Equidamoid May 19 '13 at 21:26
0

You can create a generic solution that prints the contents of object fields by subclassing PrettyPrinter. obj.__dict__ will give you a dictionary of all fields of obj.

Or you can just use obj.__class__.__name__ + pformat(obj.__dict__).

utapyngo
  • 6,946
  • 3
  • 44
  • 65