Using hist -n makes it easier to paste commands into a text
editor. To search the history, type a pattern to search for and press Ctrl-P.
When something matches, a subsequent Ctrl-P will search backward in your
history, and Ctrl-N will search forward.

Edit

When testing an idea at a Python prompt, it is sometimes helpful to edit
(and, more importantly, to reedit) some lines of source code with a text
editor. Type edit from an IPython prompt to bring up the editor
defined by the $EDITOR environment variable, or vi on
Unix and Notepad on Windows if you don't have $EDITOR defined. To
return to the IPython prompt, exit the editor. Saving and exiting will execute,
in the current namespace, the code entered into the editor. If you do not want
IPython to execute the code automatically, use edit -x. To reedit
the last code that you edited, type edit -p. In the previous
feature, I mentioned hist -n making it easier to paste code into
an editor. An even easier way of putting code into an editor is using
edit with Python list slice syntax. Suppose hist
yields:

Debugger Access

Another feature within IPython is its access to the Python debugger. Type
the pdb magic word from the IPython shell to toggle automatic
debugging upon hitting an exception. With automatic pdb calling enabled, the
Python debugger will start automatically when Python encounters an unhandled
exception; the current line in the debugger will be the line of code on
which the exception occurred. The IPython author states that sometimes when he
wants to debug something at a certain line of code, he will put
1/0 at the point he wants to begin debugging, enable pdb, and run
the code in IPython. When the interpreter hits the 1/0 line of
code, it raises a ZeroDivisionError exception and drops
him into a debugging session at that particular line.

Run

Sometimes, when in an interactive shell, it is helpful to execute the
contents of a Python source file. Issuing the run magic command followed by a
Python source file will run the file in the IPython interpreter (for example,
run <run options> <python source file>
<options>). The following run options are available:

-n prevents the __name__ variable from being
set to "__main__" for the Python source file. This prevents the
execution of any code in an

if __name__ == "__main__":

block.

-i runs the file in the current IPython namespace rather
than a new one. This is helpful if you want the Python source file to have
access to variables defined in the interactive session.

-p runs and profiles the file using the Python profiler
module. This option does not bring the executed code into the current
namespace.

Macros

Macros allow a user to associate a name with a section of Python code so the
code can be run later by referring to the name. As with the edit
magic word, the list slice notation also works with macro definitions. For
example, for a history such as:

In [3]: hist
1: l = []
2:
for i in l:
print i

you can define a macro with:

In [4]: macro print_l 2
Macro `print_l` created. To execute, type its name (without quotes).
Macro contents:
for i in l:
print i

Execute it via:

In [5]: print_l
Out[5]: Executing Macro...

In this case, the list l was empty, so it did not print
anything. However, and here is a powerful feature of macros, binding the list
l to something and then executing the macro again produces a
different result:

It is as if you retyped and executed the code contained in the macro
print_l when calling the macro again. It had access to the new
binding of the variable l. While macros are absent from Python
syntax (and probably always will be), it is certainly a useful feature in an
interactive shell.

Profiles

As mentioned earlier, IPython installs multiple configuration files for
several different profiles. The configuration files have a naming convention of
ipythonrc-<profile name>. In order to start IPython with a specific
profile, execute IPython with:

ipython -p <profile name>

One method of creating your own profile is to create an IPython
configuration file in the $HOME/.ipython directory named
ipythonrc_<your profile> where <your profile> is the
name with which you will refer to your profile. This can be useful if you have
several projects you work on and each project requires the use of specific,
different libraries. You can create a profile for each project and import the
modules you frequently use for that project in the configuration file for each
project.

System Shell Access

In the default IPython profile, the Unix shell commands (on Unix, of course)
cd, pwd, and ls all work like they do
from a bash shell. To execute any other shell commands, prepend a
! or !! to them. Use the %sc and
%sx magic words to capture the output from shell commands.

The pysh profile is intended as a shell replacement. Starting
IPython with a -p pysh flag will cause IPython to accept and execute
any commands in the user's $PATH, while at the same time allowing
access to all Python modules as well as all Python keywords and built-in
functions. For example, to create 500 directories named d_0_d through
d_500_d, start IPython with a -p pysh and do something
like this:

jjones@cerberus[foo]|2> for i in range(500):
|.> mkdir d_${i}_d
|.>

This will create 500 directories:

jjones@cerberus[foo]|8> ls -d d* | wc -l
500

Notice the mix of the Python range function and the Unix
mkdir command.

Note, however, that while ipython -p pysh can provide a
powerful shell replacement, it lacks proper job control. Pressing Ctrl-Z
while performing some long-running task will stop the IPython session rather
than the running subprocess.

Gotchas

While the Python replacement shell is excellent overall, two things provided a
small amount of trouble for me. To the credit of the IPython developers, both
items are configurable with clear documentation.

The first item was the coloring. On one of my systems, I use xterms with a
white background. When requesting information from an object or module with the
? and ?? operators, the object definition line
appeared, but it looked like the arguments were missing. That was because the
arguments in the constructor displayed in white by default. I resolved this by
entering colors LightBG at the IPython shell.

The second item was the combination of autoindent and pasting code. With
autoindent enabled, IPython double-indented a section of code I pasted
that already had indentation. For example, the following code:

for i in range(10):
for j in range(10):
for k in range(10):
pass

became:

for i in range(10):
for j in range(10):
for k in range(10):
pass

which really was not a problem in this case, because the indentation was
consistent among itself. In other circumstances (examples of which elude me
just now), it may present a real problem. Invoking the autoindent
magic word toggles autoindent so it will not add extra indents--similar to
set paste in vim.

Conclusion

IPython is not revolutionary, nor is it entirely novel. Tab completion,
searchable history, profiles, and config files have existed in other shells for
years, and Python has had levels of introspection for quite some time now.
However, IPython has unified some of the most powerful features of mature Unix
shells, the Python standard shell, and the Python language into one utility. The
result is an unbelievably powerful performance-enhancing tool that I will
likely use for years to come. To paraphrase Archimedes, give me a powerful and
flexible text editor (vim), interactive shell (IPython), and language (Python),
and I can move the world.