[IPython-user] Modifying stdout

Fernando Perez fperez.net@gmail....
Wed Feb 11 00:25:39 CST 2009


Hi,

On Sun, Feb 8, 2009 at 9:43 AM, Dan Yamins <dyamins@gmail.com> wrote:
> Hi,
>
> I'd like to redirect stdout for my own custom purposes while in an ipython
> session.  To do this, I would like to issue the command:
>
>      >  sys.stdout = multicaster(,'LogFile.txt', sys.__stdout__)
>
> before going on do my business.    The multicaster class (the code of which
> I provide below after this short explanation) is used to both log stdout
> output to a logfile ('Log.txt' in the example above) as _well_ as print to
> the screen.  Basically when multicaster does is create a new object whose
> "write" method is like that of sys.__stdout__ but also includes writing to
> the log file.
>
> When I do this at a regular python interpreter, it works fine as far as I
> can tell.   However, in ipython it wrecks havoc on ipython's interactive
> before:  the up, back, right, and left arrow keys produce output ('[[A' or
> the like) instead of their usual functions, the interactive warning after
> typing "quit()" fails, etc....   Before getting it to act normally, I have
> to issue the command:
>
>     > sys.stdout = sys.__stdout__
>
> and once I do this, all is normal again (though of course I've lost my
> special logging feature).
>
> It seems to me that the reason this is happening is probably that ipython
> has already replaced sys.stdout with an object having some special methods
> to achieve some of ipython's special interactive functionality, and my
> Multicaster class definition is overwriting those methods.  (since after all
> I'm not subclassing anything, the object I create just has one "write"
> method.)   So I have two questions:
>
> 1) Is this explanation basically right? If so, how do I properly "subclass"
> ipython's object to simply modify the write method without killing the other
> methods.

Not quite:

maqroll[scipy]> python
Python 2.5.2 (r252:60911, Oct  5 2008, 19:24:49)
[GCC 4.3.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> sys.stdout
<open file '<stdout>', mode 'w' at 0xb7e12068>
>>> import IPython.Shell
>>> IPython.Shell.start().mainloop()
Python 2.5.2 (r252:60911, Oct  5 2008, 19:24:49)
Type "copyright", "credits" or "license" for more information.

IPython 0.9.1 -- An enhanced Interactive Python.
?         -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help      -> Python's own help system.
object?   -> Details about 'object'. ?object also works, ?? prints more.

In [1]: sys.stdout
Out[1]: <open file '<stdout>', mode 'w' at 0xb7e12068>

As you can see above, ipython's stdout is the bare python one.  The
problem is that your class is missing a ton of other attributes.

You could try (but I'm not 100% sure this will work) to write an
object that is a bit more careful, and delegates *every* attribute
access to the real sys.stdout except for write() calls, which it logs.

Let us know if you try this and need any further assistance.

Best,

f


More information about the IPython-user mailing list