IPython representation of classes

2019-07-21 21:11发布

问题:

I was trying IPython with a module I created and it does not show the actual representation of class objects. Instead it shows something like

TheClass.__module__ + '.' + TheClass.__name__

I heavily use metaclasses in this module and I have really meaningful class representations that should be shown to the user.

Is there an IPython specific method I can change to make the right representation available instead of this namespace thingy that is quite useless in this application?

Or, if that's not possible, how can I customize my version of IPython to show the information I want?


EDIT

As complementary information, if I get a class and change the __module__ attribute to e.g. None, it blows with this traceback when trying to show the representation:

Traceback (most recent call last):
  ... [Huge traceback] ...
  File "C:\Python32\lib\site-packages\IPython\lib\pretty.py", line 599, in _type_pprint
    name = obj.__module__ + '.' + obj.__name__
TypeError: unsupported operand type(s) for +: 'NoneType' and 'str'

So my expectations were right and this function is used to show class objects:

def _type_pprint(obj, p, cycle):

I tried customizing it in my class but I don't think I'm doing it right. This module IPython.lib.pretty does have a big dictionary linking type (the parent of metaclasses) with this function.


EDIT 2

Things I tried:

  1. Adding the _repr_pretty_ function to metaclass. It do work with instances but not with classes...
  2. Using this function IPython.lib.pretty.for_type(typ, func). It only changes the big dictionary a wrote above but not the copy of it made by the RepresentationPrinter instance... So this function has no use at all?!
  3. Calling the magic function %pprint. It disables (or enables) this pretty print feature, using the default Python __repr__ for all the objects. That's bad because the pretty printing of lists, dict and many others are quite nice.

The first approach is more of what I want because it does not affect the environment and is specific for this class.

回答1:

This is just an issue with IPython 0.12 and older versions. Now is possible to do:

class A(type):
    def _repr_pretty_(cls, p, cycle):
        p.text(repr(self))

    def __repr__(cls):
        return 'This Information'

class B:   #or for Py3K: class B(metaclass=A):
    __metaclass__ = A

and it'll show the desired representation for B.