Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
597 views
in Technique[技术] by (71.8m points)

python - How to override ipython displayhook?

I have defined my own displayhook that inherits from IPython.core.displayhook.DisplayHook.

I was unable to find any resources online as for the proper way of overriding the displayhook for an IPython shell. Currently, I am doing the following in ~/.ipython/profile_default/startup/imports.py:

ipyShell = IPython.get_ipython()
ipyShell.displayhook = MyDisplayHook(shell=ipyShell)
ipyShell.displayhook_class = MyDisplayHook
sys.displayhook = ipyShell.displayhook

Which does not work, as after the ipython shell starts up, sys.displayhook is somehow switched back to the regular ipython display hook:

In [5]: print sys.displayhook
<IPython.core.displayhook.DisplayHook object at 0x7f1491853610>

Thanks.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

In case someone stumbles on this (like I did), the way to format IPython can actually be misleading at first glance when compared to the standard python displayhook.

In this answer, I try to detail first the different parts of IPython to clarify, then tackle the specific question of the OP (and mine) at the end.

In IPython, you can customize almost everything, only using methods that are quite far from the standard python displayhook.

What is called "hooks" in IPython (see the doc and this example) is actually something aimed at altering the behavior of the shell.

Alternatively can change how the editor looks like, i.e. the

In [5]: def foo():
   ...:     return 'foo'
   ...:

interface, and specifically the In [5]: and ...: parts. For that, you can have a look at the IPython doc to see how to do that with Prompts.

Eventually, to alter how the output of a python object is formatted, I had to use the IPython formatters (cf. source code) and the pretty printing functions defined here.

For instance, if you want to change the default dict formatting from

{'axon_angle': 305.010625458 degree,
 'observables': ['length',
   'num_growth_cones'],
 'random_rotation_angles': True}

to

{
  'axon_angle'            : 305.010625458 degree,
  'observables'           : [
    'length',
    'num_growth_cones',
  ],
  'random_rotation_angles': True
}

You can use something like

def dict_formatter(obj, p, cycle):
    if cycle:
        return p.text('{...}')
    start = '{'
    end   = '}'
    step = 2
    p.begin_group(step, start)
    keys = obj.keys()
    max_len = 0
    for k, v in obj.items():
        max_len = max(max_len, len(str(k)))

    if obj:
        p.breakable()
    for idx, key in p._enumerate(keys):
        if idx:
            p.text(',')
            p.breakable()
        p.pretty(key)
        wlen = max_len-len(str(key))
        p.text(' '*wlen + ': ')
        p.pretty(obj[key])
    if obj:
        p.end_group(step, '')
        p.breakable()
        p.text(end)
    else:
        p.end_group(step, end)

import IPython
ip = IPython.get_ipython()
formatter = ip.display_formatter.formatters['text/plain']
formatter.for_type(dict, dict_formatter)

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

57.0k users

...