[IPython-user] Re: getting values from "magic" functions

Fernando Perez Fernando.Perez at colorado.edu
Mon Sep 13 16:37:53 CDT 2004


Hi,

[this was auto-discarded because the ipython lists reject non-subscriber 
posts.  I added Christopher.Dunn at Freescale.com to the whitelist, but you 
should subscribe for future use]

> ------------------------------------------------------------------------
> 
> Subject: getting values from "magic" functions
> From: Christopher Dunn <Christopher.Dunn at Freescale.com>
> Date: Sun, 12 Sep 2004 15:48:12 -0500
> To: ipython-user at scipy.net

> The magic functions are not very useful unless it is possible to get 
> data back from them. How is this done?
> 
> I have tried
> 
> x = @ls #of course this does not work
> x = magic_ls()
> x = lsmagic()
> x = magic_lsmagic()
> x = __IP.magic_ls()
> x = __IP.magic_lsmagic()
> x = __IP.lsmagic()
> 
> 
> Nothing works.
> 
> I am trying to set up a custom extension to pass Tcl commands onto a Tcl 
> interpretter and retrive the result. Tkinter has a send() command which 
> makes this easy, but I want to take advantage of the auto paren/comma.
> 
> IPython would then be a nice front-end to any of the Tcl shells that 
> people in my industry are so fond of. (I am trying to get my co-workers 
> off Tcl, but the vendor tools use Tcl.)

Well, most magics print to stdout and return None, which is why you don't see 
an Out[XXX] prompt after calling one.  A few of them do return values, such as 
@sx, for example.  There are good reasons for this: for example, I don't want 
to get into the business of capturing and reformatting every system command 
which prints output, esp. because returned strings are normally printed in 
Out[XXX] with embedded newlines.  I won't change this, since it is the normal 
python behavior, but I doubt you really want to see the output of 'ls' as:

In [10]: ls
Out[10]: 'aa b c\naa b 
d\nargv.py\nbar.py\nbar.pyc\ndie.py\ndie.py~\ndiv.c\ndiv.f\ndiv.py\nerror.py\nerr.py\nerr.pyc\nexit2.py\nexit.py\nfoo.py\nimage2.eps\nimage.eps\nimage.ps\ninspectbug.py\nlcomp.py\nramptest.py\nscopes.py\nstrings.py\ntgp.py\ntimes.sh\nt.py\nvisex.py\nzoo 
bar2'

Right? I imagine you want instead:

In [11]: !ls
aa b c   bar.pyc  div.f     err.pyc   image2.eps     lcomp.py     tgp.py 
zoo bar2
aa b d   die.py   div.py    exit2.py  image.eps      ramptest.py  times.sh
argv.py  die.py~  error.py  exit.py   image.ps       scopes.py    t.py
bar.py   div.c    err.py    foo.py    inspectbug.py  strings.py   visex.py

So the point I'm trying to make is that there is a good reason behind the 
current behavior.  I also consider the magic system a control one, and it 
explicitly handles arguments differently than python functions: you call 
magics more like shell commands (no quoting, no parens, etc) than like python 
functions.  This is completely deliberate, I want to provide an efficient 
_control_ system for ipython itself, rather than a library of python functions 
(the stdlib is already there for that purpose).

If you want things which explicitly return values, there are a number of ways 
to do so:

1. If you want to capture shell output, @sc and @sx do that in various ways, 
and !! is a shorthand for @sx.  Their docstrings describe them in detail.

2. If you really want special capturing magics, you can write your own and 
supply them as extensions, easily loadable in a custom profile.  The docs have 
examples of custom-written magics.  The profile mechanism is extremely 
flexible, and allows you to very easily customize ipython in many ways, to 
provide a specialized system for any environment with minimal effort.  There 
are also several examples of this in the manual.

3. I suspect if you want functions which actually return python values, the 
right approach is to use real python functions.  Again, you could provide a 
python module with utilities for what you need, and simply preload it 
automatically via your profile customizations.

I hope this helps,

f.




More information about the IPython-user mailing list