Python Basics

Some tips and practices for using python (where to put it, how to install code, how to explore it).

Set up an environment

It's a best practice to start with a general sandbox to work and play. Buildout create very specific project oriented sorts of sandboxes, so we'll start with a more broad scoped virtualenv sandbox. Both buildout and virtualenv control what modules are available for import, but virtualenv acts more like a unmodified python interpreter. Sandbox is also all it does.

1. checkout virtualenv

$ svn co http://svn.colorstudy.com/virtualenv/trunk venv

2. make a general sandbox (like geo or orton)

$ python2.5 venv/virtualenv.py orton

WARNING: Zope doesn't work with Python 2.5 on 64-bit systems. Use

$ python2.4 venv/virtualenv.py orton

instead.

3. activate your env

$ cd orton; . bin/activate

4. create a source dir

$ mkdir src

Now you have a sandbox interpretter and a basic userland to work with. You can use easy_install to locally install packages and scripts.

for example::

$ easy_install ipython
$ pycolor < bin/pycolor

see colored python code (depending on terminal, mileage may vary)! if you use the -b and -e flags, you can get downloads into your src directory which allow you to read the code or edit it.

$ easy_install -b ./src -e PasteScript
$ cd src/pastescript; python setup.py develop

The second line is a basic "development" install that tell python to look for paste.script in src/pyflake rather than in '$VIRTUAL_ENV/lib/python2.5/site-packages'.

For example let's install and uninstall this development copy(on my mac). We'll also get to see the python interactive prompt::

$ cd $VIRTUAL_ENV
$ python
Python 2.5.1 (r251:54863, Aug  7 2007, 21:12:28) 
[GCC 4.0.1] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import paste.script
>>> paste.script.__file__
/Users/whit/dev/geo/src/pastescript/paste/script/__init__.py

[Cnt-D]
$ cd src/pastescript
$ python setup.py develop -u
$ cd $VIRTUAL_ENV
$ python
Python 2.5.1 (r251:54863, Aug  7 2007, 21:12:28) 
[GCC 4.0.1] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import paste.script
>>> paste.script.__file__
/Users/whit/dev/geo/lib/python2.5/site-packages/PasteScript-1.6.2-py2.5.egg/paste/script/__init__.pyc

[Cnt-D]

Note the differences in path for the 'paste.script' module metadata. If you look in $VIRTUAL_ENV/lib/python/site-packages/easy_install.pth you will see a list of distribution paths. This list determines what eggs and pkgs are available to the python in $venv/bin. Deleting a filepath here will remove a distribution from the path (aka uninstall it) similar to how "python setup.py develop -u" uninstalls a distribution.

Python Prompt

Rockin' the REPL

Arguably one of the nicest things in python. A super easy way to learn the language or try things or write tests.

$ python
Python 2.5.1 (r251:54863, Aug  7 2007, 21:12:28) 
[GCC 4.0.1] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>>

help is built in::

>>> help() # launches interactive help
...

You can use help to introspect modules (if you don't have readline, exit the prompt and easy_install it)::

>>> import readline
>>> help(readline)
...
    write_history_file(...)
        write_history_file([filename]) -> None
        Save a readline history file.
        The default filename is ~/.history.

(this will write you prompt session to file for later reuse as code or tests)

>>> readline.write_history_file("hot-python-sesssion.1")

You can also introspect using the builtin "dir" to see all the methods and attributes on an object, class or type::

>>> from pprint import pprint
>>> pprint(dir(list()))
[...
 'sort']

>>> class MyClassyClass(object):
...     """so classy"""
...     class_attr="classy"

>>> pprint(dir(MyClassyClass))
[...
 'class_attr']

>>> help(MyClassyClass)
class MyClassyClass(__builtin__.object)
 |  So Classy
...

Debugging

The last critical exploratory tip is that *pdb is your friend*. If you use an editor that has a pdb trace mode, it's really your friend : eclipse, emacs, textmate, wingide, komodo all support iirc.

Basic debugging works like this::

>>> class MyBrokeObject(object):
...     divisor = 0
...     def divide(self, value):
...         return value/self.divisor

>>> fubared = MyBrokeObject()
>>> fubared.divide(5)
Traceback (most recent call last):
...
ZeroDivisionError: integer division or modulo by zero

We can step into this broken method like so::

>>> import pdb
>>> pdb.set_trace(); fubared.divide(5)

s - to step into, n - for next line, help for general help, l - list lines

This works better on filesystem code and is also a handy way to peak inside existing modules and see what makes them tick::

>>> pdb.set_trace(); readline.write_history_file("hot-python-sesssion.1")

pdb also support postmortem debugging::

>>> def do_postmortem():
...     try:
...         fubared.divide(5)
...     except :
...         import sys
...         pdb.post_mortem(sys.exc_info()[2])

>>> do_postmortem()

If this was filesystem code, you would get popped into the debugger right at the point of breakage.