Saturday, 23 November 2002

More Python goodness for 2.2 and 2.3 (updated)

Want to iterate over a file? Try this on for size:

for line in open('/etc/passwd'):  # You could also use file('/etc/passwd')
    logname, x, uid = line.split(':')[:2]
    print 'user %s has uid %s' % (logname, uid)

You'd probably want to use the pwd module instead if you need to access the passwd database portably; this was meant as a simple example. :-)

Explanation: In Python 2.2 and later, file objects have a built-in iterator, which allows the lines in a file to be iterated over in a "for" loop. This is more memory efficient than the lines=f.readlines() semantic and easier to read than using the relatively new xreadlines() method.

You can also iterate over dictionaries now, as well as any class that defines a __next__ method. This is particularly useful when combined with generators, which are basically functions that preserve state between calls. xrange() and xreadlines() are now implemented this way. Of course, sequences (lists, tuples, strings) have their own built-in iterators too for backwards-compatibility :-)

Python 2.2 also has additional cool dictionary features; you can use "in" and "not in" instead of using dict.has_key(). "in" can also be implemented in classes using the __contains__ method. (Also, 2.3 extends "in" to allow multicharacter strings, so you can use the much cleaner if 'hell' in 'hello' instead of if 'hello'.find('hell') != -1.)

Another productivity tip for 2.2 and later: use help(object) at the interpreter prompt to get documentation for that object; it works best with modules and classes.