[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