IPython – Interactive Python shell
Monday, October 29th, 2007
(The latest version of this introduction to IPython can always be found here)
Python has an interactive shell, which you can start by simply starting
python:
[todsah@jib]~$ python Python 2.4.4 (#2, Apr 5 2007, 20:11:18) [GCC 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> print('hello') hello
This is a nice and very powerful way of using Python, but it’s a bit
limited. So you might want to check out IPython.
IPython is also an interactive Python shell, but with lot’s of stuff added,
such as tab completion, colors, dynamic object introspection, sessions,
command history, etc.
To start it, simply run the IPython command:
[todsah@jib]~$ ipython Python 2.4.4 (#2, Apr 5 2007, 20:11:18) Type "copyright", "credits" or "license" for more information. IPython 0.8.0 -- An enhanced Interactive Python. ? -> Introduction to IPython's features. %magic -> Information about IPython's 'magic' % functions. help -> Python's own help system. object? -> Details about 'object'. ?object also works, ?? prints more. In [1]:
You’ll be dropped at a prompt (In [1]:) where you can enter python
commands, just like in the normal interactive python interpreter. Let’s walk
through a couple of IPython’s best features:
Tab completion
IPython has smart tab completion for lots of things such as modules,
classes, methods and directory/files. For instance, we can define a class:
In [7]: class Foo: ...: """ Example class """ ...: def bar(self, name): ...: """ Example method """ ...: print("Hello %s!" % (name)) ...:
Then, when we want to create an instance of that class, we can use tab
completion to find the possible completion names:
In [8]: f = F[TAB] False FloatingPointError Foo FutureWarning In [8]: f = Foo()
Tab completion will also help you with methods in classes:
In [11]: Foo.[TAB] Foo.__doc__ Foo.__module__ Foo.bar
Another example of tab completion is when you need to specify a filename:
In [9]: pw = file('/etc/pa[TAB] /etc/pam.conf /etc/pam.d /etc/pango /etc/paper.config /etc/papersize /etc/passwd /etc/passwd-
In [9]: pw = file('/etc/pas[TAB] /etc/passwd /etc/passwd- In [9]: pw = file('/etc/passwd')
Documentation
We can also use IPython features to retrieve information on all kinds of
stuff by appending a question mark behind it:
In [10]: Foo? Type: classobj String Form: __main__.Foo Namespace: Interactive File: /var/lib/python-support/python2.4/IPython/FakeModule.py Docstring: Example class In [15]: file? Type: type Base Class: String Form: Namespace: Python builtin Docstring: file(name[, mode[, buffering]]) -> file object Open a file. The mode can be 'r', 'w' or 'a' for reading (default), writing or appending. The file will be created if it doesn't exist when opened for writing or appending; it will be truncated when opened for writing. Add a 'b' to the mode for binary files. Add a '+' to the mode to allow simultaneous reading and writing. If the buffering argument is given, 0 means unbuffered, 1 means line buffered, and larger numbers specify the buffer size. Add a 'U' to mode to open the file for input with universal newline support. Any line ending in the input file will be seen as a 'n' in Python. Also, a file so opened gains the attribute 'newlines'; the value for this attribute is one of None (no newline read yet), 'r', 'n', 'rn' or a tuple containing all the newline types seen. 'U' cannot be combined with 'w' or '+' mode. Note: open() is an alias for file().
The above works on almost anything from modules to methods. Documentation in
another form can also be retrieved using the help function (also available
in the default python interpreter):
In [11]: help Foo Help on class Foo in module __main__: class Foo | Example class | | Methods defined here: | | bar(self, name) | Example method |-> help(Foo)
Another little something that could come in handy: Searching the namespaces
for wildcards:
In [55]: ?*oo Foo In [56]: ?*ile compile execfile file
Editing in an editor
IPython provides a couple of interesting ‘magic’ functions. These do
anything from acting as an actual system shell (ls, cd, etc) as well as
providing access to some settings and other features. One such feature is
the ability to call an external editor to quickly edit multi-line Python
code:
In [19]: %edit IPython will make a temporary file named: /tmp/ipython_edit_vpMbMW.py [EDITOR IS LAUCHED] Editing... done. Executing edited code... Out[19]: 'class Foo:\n\tdef Bar(self):\n\t\treturn("hello, world!")\n\n'
It shows the code we typed in the editor as a single line of output and runs
it. class Foo is now defined. We can revisit the code we typed in the editor
by using the output number given: Out[19]:
In [20]: %edit _19 IPython will make a temporary file named: /tmp/ipython_edit_r7EqK7.py Editing... done. Executing edited code... Out[20]: 'class Foo:\n\tdef Bar(self):\n\t\treturn("goodbye world!")\n\n'
By the way, _19 is nothing more than a special variable that contains the
output of command 19 in the interactive shell:
In [21]: print _19 class Foo: def Bar(self): return("hello, world!")
%edit _19 simply says we want to edit the contents of that variable. That
%means we can also do things such as:
In [22]: s = "This is some string\nWhat should we do with it?" In [23]: edit s IPython will make a temporary file named: /tmp/ipython_edit_VelPpw.py Editing... done. Executing edited code... ____________________________________________________________ File "/tmp/ipython_edit_VelPpw.py", line 1 This is some string ^ SyntaxError: invalid syntax WARNING: Failure executing file: </tmp/ipython_edit_VelPpw.py> Out[23]: 'This is some string\nWhat should we do with it?\nEdit it!\n'
This will give us a better view of the contents of the variable ‘s’, which
can be useful for stuff retrieved from a file, for instance. IPython won’t
reassign the edited text to the variable, but this can be easily
accomplished by assigning the output of Out[23] to the variable s:
In [24]: s = _23 In [25]: s Out[25]: 'This is some string\nWhat should we do with it?\nEdit it!\n'
Another special variable is ‘_’ which is the last output received. This
can be used to consecutively edit a piece of code until it’s free of syntax
errors:
In [42]: %edit IPython will make a temporary file named: /tmp/ipython_edit_nWOuiK.py Editing... done. Executing edited code... File "/tmp/ipython_edit_nWOuiK.py", line 2 de bar(self): ^ SyntaxError: invalid syntax WARNING: Failure executing file: </tmp/ipython_edit_nWOuiK.py> Out[42]: 'class Foo:\n\tde bar(self):\n\t\tprint "Hello, world"\n\n' In [43]: %edit _ IPython will make a temporary file named: /tmp/ipython_edit_U-ylh8.py Editing... done. Executing edited code... Out[43]: 'class Foo:\n\tdef bar(self):\n\t\tprint "Hello, world"\n\n'
Debugging
IPython also has a built-in debugger that can be used to inspect tracebacks
in a post-mortem. Let’s take the following code:
def f1(param1): f2(param1) def f2(param2): if type(param2) != type(int): raise ValueError("expected an integer", 1)
When we %edit this, and execute it, and then call f1('foo') it will
generate an exception:
In [53]: f1('foo') ____________________________________________________________ exceptions.ValueError Traceback (most recent call last) /home/todsah/ /tmp/ipython_edit_qrYEq0.py in f1(param1) ...-> 2 f2(param1) 3 def f2(param2): 4 if type(param2) != type(int): 5 raise ValueError("expected an integer", 1) 6 /tmp/ipython_edit_qrYEq0.py in f2(param2) 2 f2(param1) 3 def f2(param2): 4 if type(param2) != type(int): ...-> 5 raise ValueError("expected an integer", 1) 6 ValueError: ('expected an integer', 1)
Now, we can activate the post-mortem debugger and inspect various things:
In [54]: %debug > /tmp/ipython_edit_qrYEq0.py(5)f2() 4 if type(param2) != type(int): ...-> 5 raise ValueError("expected an integer", 1) 6 ipdb>
Here, we’ve landed at the debugger prompt. The help command can help us:
ipdb> help Documented commands (type help ): ======================================== EOF break condition disable help list pdoc r u where a bt cont down ignore n pinfo return unalias alias c continue enable j next pp s up args cl d exit jump p q step w b clear debug h l pdef quit tbreak whatis Miscellaneous help topics: ========================== exec pdb Undocumented commands: ====================== retval rv
People familiar with other debuggers such as GDB will notice familiar stuff.
I won’t go into the details, but consider this little session as an example
of what you can with the debugger:
ipdb> p param2 'foo' ipdb> p type(param2) <type 'str'> ipdb> up > /tmp/ipython_edit_qrYEq0.py(2)f1() 1 def f1(param1): ----> 2 f2(param1) 3 def f2(param2): ipdb> p param1, type(param1) ('foo', <type 'str'>)
This can be used in combination with the %run command to execute a python
file:
In [67]: %run raise.py ____________________________________________________________ exceptions.Exception Traceback (most recent call last) /home/todsah/raise.py 1 #!/usr/bin/python 2 ----> 3 raise Exception("Some error!", 1) 4 5 Exception: ('Some error!', 1) WARNING: Failure executing file:
(ignore that last line. It did in fact succeed at executing the file. It’s
just that an error occurred while executing it).
Other stuff
The reload() method reloads a module. This can come in handy when you’re
writing a module and keep changing it and you want those changes to be
reloaded by IPython:
In [75]: import sys In [76]: reload(sys)
Conclusion
IPython is a very versatile tool for interactive python programming. It
allows you to quickly inspect modules, classes, methods, documentation and a
lot more. Not sure if that list comprehension is going to give you
exactly what you want? Fire up IPython and just try it out! Whenever I’m
writing Python code, I’ll always have an IPython shell open for
experimenting with code or for finding information. Try it, and you’ll find
that IPython is an indispensable tool.