22.9.05. Some Favorite Python "Anti-Pitfalls"

I saw a link to this today - a list of Python anti-pitfalls, written back in 2003 by Richard Jones. There are a couple that I'd like to add boisterous comment to.

11. No namespace pollution (unless you really want to)
Unless you explicitly do from foo import *, all names are contained within modules / classes / objects. I love Python packages and modules. Every time I work with another language, like my rare excursions into Perl or Ruby, or my recent working with Javascript, I'm reminded of why I love this feature.

from zope.interface import Interface
import zope.schema

class IFoo(Interface):
    title = zope.schema.TextLine(...)

A very simple example. But in Ruby, for example, require 'xml/parser' is then used in code as XML::Parser - a name that is similar but different to what was in the require statement. In Python, that might look like import xml.parser and then be used as xml.parser.Parser. The last time I used Perl, I was always staring at names that I needed to use and wondering exactly where that name came from. I use neither language enough to know the difference between 'require' and 'use' (PHP suffers from this as well). Python's Modula influence is perhaps one of its strongest features. It makes large frameworks like Zope 3 and Twisted actually quite easy to understand and follow.

So with Python, every name that I see in code I can easily trace, unless the code's author uses multiple 'from foo import *' style statements or does some namespace manipulation magic. I try to avoid those these days, wherever possible.

12. The python shell (interactive interpreter)
I learn best by trial and exploration, and the excellent Python interactive interpreter is probably the number one reason that I'm a Python programmer at all. I was raised on computers like the Commodore 64 which pretty much had the BASIC language/environment loaded at all times, so I could immediately try out small or large chunks of code. Python was the first language since those early days that brought me the same joy. On a daily basis, I still drop into the interpreter to introspect objects or just to try out how something might work. For learning something new - I recently used the interpreter to figure out how to dynamically build a zip file of CSV files while never actually building a file on the file system. I was able to explore using the csv, StringIO, and zipfile modules together in the interpreter before integrating the code into my project.

Recent versions of Zope (both Zope 2 and Zope 3) make it easy to load up the Python interpreter with the ZODB and Zope system loaded. I was able to use this the other day to dig deep into some indexes to figure out why some search results weren't behaving as I expected. It turned out that I was querying the index incorrectly, but it was a behavior that didn't show itself based on the first set of data that was loaded in our ZODB database.

This interactive interpreter is available at all times. It is Python. It's one of the many features that makes working with Python without all of the weight of an IDE possible.

13. PDB
PDB is the Python debugger. This is the other feature that makes working with Python without all of the weight of an IDE possible. Sometimes, I have problems in Zope that can't be figured out with some other debugging means (logging, etc). When running Zope so that it doesn't detach from the shell, having the following statement in the Python code: import pdb; pdb.set_trace() basically puts a breakpoint in the code and when those two statements are executed (the pdb module is imported and the set_trace() function is called), Python drops to a 'pdb' shell inside of the interpreter. From here, I can step through code, inspect variables, go up and back down the call stack, and even import and use other code to help me in my inspection. When the problem is solved, deleting the 'import pdb; pdb.set_trace()' line is all that's needed to remove the breakpoint. Again - this is doable without an IDE and is available anywhere - even on the most stripped down server configuration.

There are many other anti-pitfalls in Python in Richard's list. These three (which just happened to be sequential) are the three that I'm most grateful for and are all elements of Python that I've used happily for almost ten years now, even while other new (and welcome) features and modules have come into the language since those Python 1.3 days.