简体   繁体   中英

Paging stdout output in IPython

Is it possible in an (interactive) IPython session to pass the stdout output through a pager, like less ? If so, how?

For example, in

In [1]: from some_module import function_that_prints_a_lot

In [2]: function_that_prints_a_lot()

... everything scrolls away ...

I would like to page through the stdout output of function_that_prints_a_lot .

Another example:

In [1]: %run script_that_prints_a_lot.py

I've looked through IPython magic commands but didn't find any solution.

As discussed in chat there is no simple way of doing this. Since the function prints the values, the only thing you can do is Capture output + Then page output. There are few issues on jupyter that you might be interested in

https://github.com/jupyter/notebook/issues/2049

https://github.com/ipython/ipython/issues/6516

Capturing output

Output capturing can be done multiple ways

1. Overload Print Method

import sys
data = ""
def myprint(value, *args, sep=' ', end='\n', file=sys.stdout, flush=False):
    global data
    current_text = value + " ".join(map(str, args)) + "\n"
    data += current_text

original_print = print
print = myprint

def testing():
    for i in range(1,1000):
        print ("i =", i)

testing()

original_print("The output from testing function is", data)

2. Capture output using StringIO

from cStringIO import StringIO
import sys

class Capturing(list):
    def __enter__(self):
        self._stdout = sys.stdout
        sys.stdout = self._stringio = StringIO()
        return self
    def __exit__(self, *args):
        self.extend(self._stringio.getvalue().splitlines())
        del self._stringio    # free up some memory
        sys.stdout = self._stdout

Usage:

with Capturing() as output:
    do_something(my_object)

3. Capture output using redirect_stdout

import io
from contextlib import redirect_stdout

f = io.StringIO()
with redirect_stdout(f):
    do_something(my_object)
out = f.getvalue()

4. Capture using %%capture magic command

捕捉魔法

Paging Output

You can use magin %page

%page -r <variablename>

https://ipython.readthedocs.io/en/stable/interactive/magics.html#magic-page

Or you can use Ipython code

from IPython.core import page
page.page(variable)

For more details refer to below

PS: Some helpful threads

How to capture stdout output from a Python function call?

How can I redirect print output of a function in python

https://github.com/ipython/ipython/wiki/Cookbook:-Sending-built-in-help-to-the-pager

overload print python

Using bits and pieces from various sources, but essentially it's from IPython's cookbook and Defining custom magics from IPython official documentation

In [1]: from IPython.core.magic import register_line_magic

In [2]: @register_line_magic
   ...: def my_pager(line):
   ...:     "my line magic"
   ...:     import io
   ...:     from IPython.core import page
   ...:     from contextlib import redirect_stdout
   ...:     f = io.StringIO()
   ...:     with redirect_stdout(f):
   ...:         eval(line)
   ...:     page.pager_page(f.getvalue())
   ...: del my_pager # don't pollute my namespace    

In [3]: def pippo(): print('\n'.join(str(i)for i in range(80)))

In [4]: %my_pager pippo()

This approach has a serious drawback: if the function call that is the argument to %my_pager returns a value, said value is lost (no, %mypager result=print_and_return() won't work...)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM