<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title type="text">Peter Hoffmann</title>
  <id>http://peter-hoffmann.com/feed/atom.xml</id>
  <updated>2010-08-17T15:20:18Z</updated>
  <link href="http://peter-hoffmann.com" />
  <link href="http://peter-hoffmann.com/feed/atom.xml" rel="self" />
  <subtitle type="text">Atom Feed for peter-hoffmann.com</subtitle>
  <generator>Werkzeug</generator>
  <entry xml:base="http://peter-hoffmann.com/feed/atom.xml">
    <title type="text">Refresh Browser on save with inotify and xdotool</title>
    <id>http://peter-hoffmann.com/2010/refresh-browser-on-save-with-inotify-and-xdotool.html</id>
    <updated>2010-08-17T15:20:18Z</updated>
    <published>2010-08-17T15:20:18Z</published>
    <link href="http://peter-hoffmann.com/2010/refresh-browser-on-save-with-inotify-and-xdotool.html" />
    <author>
      <name>Peter Hoffmann</name>
      <uri>http://peter-hoffmann.com</uri>
    </author>
    <content type="html">&lt;p&gt;The following code is a simple solution to refresh a browser window when
you save a file. It could be used with any editor and browser. It is based
on &lt;a href="http://en.wikipedia.org/wiki/Inotify"&gt;Inotify&lt;/a&gt; for file
system monitoring and &lt;a
href="http://www.semicomplete.com/projects/xdotool/"&gt;xdodool&lt;/a&gt; to send
fake keyboard input events.
&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
#!/bin/bash
FILE=$1
BROWSER=google-chrome

$BROWSER $FILE

while [ 1 -eq 1 ]; do
    inotifywait -q $FILE &gt;/dev/null
    echo "$(date --rfc-3339=seconds) Refresh: $FILE"
    CUR_WID=$(xdotool getwindowfocus)
    
    #gets the first $BROWSER window, if you have more than one
    #$BROWSER window open, it might not refresh the right one,
    #as an alternative you can search by the window/html title
    WID=$(xdotool search --onlyvisible --class $BROWSER|head -1)
    #TITLE="window/html file title"
    #WID=$(xdotool search --title "$TITLE"|head -1)
    xdotool windowactivate $WID
    xdotool key 'ctrl+r'
    xdotool windowactivate $CUR_WID
done
&lt;/pre&gt;


&lt;p&gt;If you run Ubuntu, you need to install the following packages:&lt;/p&gt;
&lt;pre&gt;
inotify-tools
xdotool
&lt;/pre&gt;
</content>
  </entry>
  <entry xml:base="http://peter-hoffmann.com/feed/atom.xml">
    <title type="text">Extrinsic Visitor Pattern in Python with support for Inheritance</title>
    <id>http://peter-hoffmann.com/2010/extrinsic-visitor-pattern-python-inheritance.html</id>
    <updated>2010-08-09T16:49:47Z</updated>
    <published>2010-08-09T16:49:47Z</published>
    <link href="http://peter-hoffmann.com/2010/extrinsic-visitor-pattern-python-inheritance.html" />
    <author>
      <name>Peter Hoffmann</name>
      <uri>http://peter-hoffmann.com</uri>
    </author>
    <content type="html">&lt;p&gt;In python you often find a slightly modified version of the classic
&lt;i&gt;Visitor Pattern&lt;/i&gt;. Instead of using a &lt;tt&gt;accept(self, visitor)&lt;/tt&gt;method
in the target class to tell the visitor what kind of object to handle, the
accept method is replaced with introspection in the visitor class:
&lt;/p&gt;

&lt;blockquote&gt;
An Extrinsic Visitor implements double dispatch with run time type
information instead of Accept() methods. With the same machinery it is
possible to test the feasibility of a particular visit before performing
its operation. The extrinsic visitor pattern provides several benefits in
ease of software development in trade for poorer run time performance.
[Variations on the Visitor Pattern - Martin Nordberg]
&lt;/blockquote&gt;

&lt;p&gt;But the implementation as shown in &lt;a
href="http://peak.telecommunity.com/DevCenter/VisitorRevisited"&gt;The Visitor
Pattern Revisited&lt;/a&gt; has the drawback to not support inheritance:&lt;/p&gt;

&lt;blockquote&gt;
There is one drawback to this approach, however. As commonly coded in
Python, the Extrinsic Visitor pattern does not have any way to deal with
inheritance.

For example, let's say your PrettyPrinter class has a visit_list() method.
And somebody subclasses list to make MyList. You're going to have to add a
visit_MyList() to your PrettyPrinter class, even though in all probability
the visit_list() method would work just fine. [&lt;a href="http://peak.telecommunity.com/DevCenter/VisitorRevisited"&gt;The Visitor Pattern Revisited&lt;/a&gt;]
&lt;/blockquote&gt;

The following code shows a solution supporting inheritance using
&lt;tt&gt;__mro__&lt;/tt&gt;, &lt;a
href="http://www.python.org/download/releases/2.3/mro/"&gt;the Python
Method Resolution Order&lt;/a&gt;:

&lt;pre class="prettyprint"&gt;
class Node(object): pass
class A(Node): pass
class B(Node): pass
class C(A,B): pass

class Visitor(object):
    def visit(self, node, *args, **kwargs):
        meth = None
        for cls in node.__class__.__mro__:
            meth_name = 'visit_'+cls.__name__
            meth = getattr(self, meth_name, None)
            if meth:
                break

        if not meth:
            meth = self.generic_visit
        return meth(node, *args, **kwargs)

    def generic_visit(self, node, *args, **kwargs):
        print 'generic_visit '+node.__class__.__name__

    def visit_B(self, node, *args, **kwargs):
        print 'visit_B '+node.__class__.__name__


a = A()
b = B()
c = C()
visitor = Visitor()
visitor.visit(a)
visitor.visit(b)
visitor.visit(c)
&lt;/pre&gt;
&lt;p&gt;If you run the code you get the following output:&lt;/p&gt;
&lt;pre&gt;
generic_visit A
visit_B B
visit_B C
&lt;/pre&gt;
&lt;p&gt;For the &lt;tt&gt;class A&lt;/tt&gt; the visitor falls back to the generic_visit
method because there is no special implementation. For &lt;tt&gt;class B&lt;/tt&gt; the
&lt;tt&gt;visit_B&lt;/tt&gt; method is used. And for &lt;tt&gt;class C&lt;/tt&gt; the
implementation walks up the &lt;tt&gt;__mro__&lt;/tt&gt;  to find a suitable method
from a  superclass B &lt;tt&gt;visit_B&lt;/tt&gt;.&lt;/p&gt;
</content>
  </entry>
  <entry xml:base="http://peter-hoffmann.com/feed/atom.xml">
    <title type="text">XML data binding with python descriptors</title>
    <id>http://peter-hoffmann.com/2010/xml-data-binding-with-python-descriptors.html</id>
    <updated>2010-07-22T14:18:11Z</updated>
    <published>2010-07-22T14:18:11Z</published>
    <link href="http://peter-hoffmann.com/2010/xml-data-binding-with-python-descriptors.html" />
    <author>
      <name>Peter Hoffmann</name>
      <uri>http://peter-hoffmann.com</uri>
    </author>
    <content type="html">&lt;p&gt;&lt;a href="http://docs.python.org/reference/datamodel.html#descriptors"&gt; Python
descriptors&lt;/a&gt; are used to represent attributes of other classes. A descriptor
must implement one or more methods of the descriptor protocol:
&lt;/p&gt;&lt;pre&gt;
__get__(self, instance, owner)
__set__(self, instance, value)
__delete__(self, instance)
&lt;/pre&gt;&lt;p&gt;There are already some great articles about descriptors from
&lt;a href="http://users.rcn.com/python/download/Descriptor.htm"&gt; Raymond Hettinger&lt;/a&gt;,
&lt;a href="http://www.informit.com/articles/article.aspx?p=1309289"&gt; Mark Summerfield&lt;/a&gt;
and &lt;a href="http://martyalchin.com/2007/nov/23/python-descriptors-part-1-of-2/"&gt;
Marty Alchin&lt;/a&gt;. Descriptors are used since python 2.2 to implement new style classes
and in 
&lt;a href="http://docs.djangoproject.com/en/dev/topics/db/queries/#related-objects"&gt;Django&lt;/a&gt;
ORM
to implement the &lt;tt&gt;ForeignKey&lt;/tt&gt;, &lt;tt&gt;OneToOneField&lt;/tt&gt; and &lt;tt&gt;ManyToManyField&lt;/tt&gt;
relations.
&lt;/p&gt;&lt;p&gt;The following code shows how you can use descriptors and
&lt;a href="http://codespeak.net/lxml/xpathxslt.html"&gt; XPath&lt;/a&gt; expressions to
access XML datastructures in a more pythonic way.
&lt;/p&gt;&lt;pre&gt;
import lxml.etree
class Bind(object):
    def __init__(self, path, converter=None, first=False):
        '''
        path -- xpath to select elements
        converter -- run result through converter
        first -- return only first element instead of a list of elements
        '''
        self.path = path
        if converter is None:
            converter = lambda x: x
        self.converter = converter
        self.first = first

    def __get__(self, instance, owner=None):
        res = instance._elem.xpath(self.path)
        if self.first:
            return self.converter(res[0])
        return [self.converter(r) for r in res]
&lt;/pre&gt;&lt;p&gt;The &lt;tt&gt;Bind&lt;/tt&gt; Descriptor expects the class instance to have a attribute
&lt;tt&gt;_elem&lt;/tt&gt; which is a &lt;tt&gt;lxml.etree._Element&lt;/tt&gt;.
&lt;/p&gt;&lt;p&gt;I'm using a sample XML response from the &lt;a href="http://isbndb.com"&gt; isbndb.com REST
Api&lt;/a&gt; to show the data-binding. 
&lt;/p&gt;&lt;pre&gt;
&amp;lt;ISBNdb server_time="2010-07-21T15:56:06Z"&amp;gt;
    &amp;lt;BookList total_results="1"&amp;gt;
        &amp;lt;BookData book_id="programming_collective_intelligence" isbn="0596529325"&amp;gt;
            &amp;lt;Title&amp;gt;Programming collective intelligence&amp;lt;/Title&amp;gt;
            &amp;lt;AuthorsText&amp;gt;Toby Segaran&amp;lt;/AuthorsText&amp;gt;
            &amp;lt;PublisherText publisher_id="oreilly"&amp;gt;O'Reilly, 2007.&amp;lt;/PublisherText&amp;gt;
        &amp;lt;/BookData&amp;gt;
    &amp;lt;/BookList&amp;gt;
&amp;lt;/ISBNdb&amp;gt;
&lt;/pre&gt;&lt;p&gt;And the data mapping:
&lt;/p&gt;&lt;pre&gt;
import dateutil

class Data(object):
    def __init__(self, elem):
        self._elem = elem

class Book(Data):
    #use xpath text() to get text 
    title = Bind('Title/text()', first=True)
    #get text via converter
    author = Bind('AuthorsText', converter=lambda x: x.text,  first=True)     
    publisher = Bind('PublisherText/text()', first=True)
    publisher_id = Bind('PublisherText/@publisher_id', first=True)

class ISBNdb(Data):
    #use the dateutil.parser to convert string to datetime
    server_time = Bind('@server_time', converter=dateutil.parser.parse, first=True)
    #convert result to integer
    total_results = Bind('BookList/@total_results', converter=int, first=True)
    #bind result to custom class which is itself a mapping
    books = Bind('//BookData', Book)
&lt;/pre&gt;&lt;p&gt;Now let's play with the mapping:
&lt;/p&gt;&lt;pre&gt;
&amp;gt;&amp;gt;&amp;gt; db = ISBNdb(lxml.etree.fromstring(test_response))
&amp;gt;&amp;gt;&amp;gt; db.server_time
datetime.datetime(2010, 7, 21, 15, 56, 6, tzinfo=tzutc())
&amp;gt;&amp;gt;&amp;gt; db.total_results
1
&amp;gt;&amp;gt;&amp;gt; db.books
[&amp;lt;Book object at 0x9c1780c&amp;gt;]
&amp;gt;&amp;gt;&amp;gt; book = db.books[0]
&amp;gt;&amp;gt;&amp;gt; book.title
'Programming collective intelligence'
&amp;gt;&amp;gt;&amp;gt; book.author
'Toby Segaran'
&amp;gt;&amp;gt;&amp;gt; book.publisher
"O'Reilly, 2007."
&amp;gt;&amp;gt;&amp;gt; book.publisher_id
'oreilly'
&lt;/pre&gt;&lt;p&gt;The source code from this example is available on
&lt;a href="http://gist.github.com/485977"&gt;gist.github.com/485977&lt;/a&gt;.&lt;/p&gt;</content>
  </entry>
  <entry xml:base="http://peter-hoffmann.com/feed/atom.xml">
    <title type="text">Digg import feeds and verification</title>
    <id>http://peter-hoffmann.com/2010/digg-import-feed-verify-key.html</id>
    <updated>2010-07-18T13:02:56Z</updated>
    <published>2010-07-18T13:02:56Z</published>
    <link href="http://peter-hoffmann.com/2010/digg-import-feed-verify-key.html" />
    <author>
      <name>Peter Hoffmann</name>
      <uri>http://peter-hoffmann.com</uri>
    </author>
    <content type="html">&lt;p&gt;The new &lt;a href="http://new.digg.com"&gt;Alpha Digg&lt;/a&gt; lets you auto-import your content.
They want you to verify that you are the owner of the content. But instead of
using the open &lt;a href="http://microformats.org/wiki/rel-me"&gt;Microformats&lt;/a&gt; standard
&lt;tt&gt;rel="me"&lt;/tt&gt; like &lt;a href="http://google.com/profiles/tosh54"&gt;Google Buzz&lt;/a&gt; does,  you have
to add a verification key to one of you posts. 
&lt;/p&gt;
&lt;p&gt;Verify Key: 651a6fa177724b03b9d33e37652831c7 
&lt;/p&gt;
</content>
  </entry>
  <entry xml:base="http://peter-hoffmann.com/feed/atom.xml">
    <title type="text">Geocron uses Google Latitude to provide locationbased cron jobs</title>
    <id>http://peter-hoffmann.com/2010/geocron-google-latitude-locationbased-cron-job.html</id>
    <updated>2010-07-13T14:12:03Z</updated>
    <published>2010-07-13T14:12:03Z</published>
    <link href="http://peter-hoffmann.com/2010/geocron-google-latitude-locationbased-cron-job.html" />
    <author>
      <name>Peter Hoffmann</name>
      <uri>http://peter-hoffmann.com</uri>
    </author>
    <content type="html">&lt;p&gt;
&lt;a href="http://geocron.us/"&gt;Geocron&lt;/a&gt; provides location aware cron jobs. It
uses the &lt;a href="http://code.google.com/apis/latitude/"&gt;Google Latitude
API&lt;/a&gt; to get your location and send automated email, SMS, or webhook
pyloads.
&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;We used several interesting technologies for the project. Because we
already needed to use Google's Latitude API, we opted to handle sign up
completely through Google Accounts and OAuth. For the app itself, we used the
excellent lightweight Python framework called &lt;a
href="http://flask.pocoo.org/docs/"&gt;Flask&lt;/a&gt;. It seems to have been inspired
by &lt;a href="http://sinatrarb.com"&gt;Sinatra&lt;/a&gt;, which powers a &lt;a
href="http://sunlightlabs.com/blog/2010/drumbone-api/"&gt;few&lt;/a&gt; of &lt;a
href="http://sunlightlabs.com/blog/2010/national-data-catalog-api/"&gt;our&lt;/a&gt;
APIs here at Sunlight. Last, but certainly not least, we used &lt;a
href="http://mongodb.org"&gt;MongoDB&lt;/a&gt; as our backing data store. It was
Kaitlin's first time working with Mongo, and she quickly took to it. Like I've
said before, things tend to &lt;a
href="http://sunlightlabs.com/blog/2010/how-we-use-mongodb-sunlight/"&gt;just
click&lt;/a&gt; when working with it. [&lt;a
href="http://sunlightlabs.com/blog/2010/labs-olympics-geocron/"&gt;sunlightlabs.com&lt;/a&gt;]
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You should keep clearly in mind the privacy issues, but
from an engineering point of view it is a great service. The source code is
avaliable on &lt;a
href="http://github.com/jcarbaugh/geocron"&gt;github&lt;/a&gt;.&lt;/p&gt;
</content>
  </entry>
  <entry xml:base="http://peter-hoffmann.com/feed/atom.xml">
    <title type="text">Retry Decorator in Python</title>
    <id>http://peter-hoffmann.com/2010/retry-decorator-python.html</id>
    <updated>2010-07-10T12:14:57Z</updated>
    <published>2010-07-10T12:14:57Z</published>
    <link href="http://peter-hoffmann.com/2010/retry-decorator-python.html" />
    <author>
      <name>Peter Hoffmann</name>
      <uri>http://peter-hoffmann.com</uri>
    </author>
    <content type="html">&lt;p&gt;The retry decorator reruns a funtion &lt;tt&gt;tries&lt;/tt&gt; times if an exception occurs.
&lt;/p&gt;
&lt;pre class="prettyprint"&gt;
import time

class Retry(object):
    default_exceptions = (Exception)
    def __init__(self, tries, exceptions=None, delay=0):
        """
        Decorator for retrying a function if exception occurs
        
        tries -- num tries 
        exceptions -- exceptions to catch
        delay -- wait between retries
        """
        self.tries = tries
        if exceptions is None:
            exceptions = Retry.default_exceptions
        self.exceptions =  exceptions
        self.delay = delay

    def __call__(self, f):
        def fn(*args, **kwargs):
            exception = None
            for _ in range(self.tries):
                try:
                    return f(*args, **kwargs)
                except self.exceptions, e:
                    print "Retry, exception: "+str(e)
                    time.sleep(self.delay)
                    exception = e
            #if no success after tries, raise last exception
            raise exception
        return fn

&lt;/pre&gt;
&lt;p&gt;Usage:&lt;/p&gt;
&lt;pre class="prettyprint"&gt;
&amp;gt;&amp;gt;&amp;gt; from retry_decorator import Retry
&amp;gt;&amp;gt;&amp;gt; @Retry(2)
... def fail_fn():
...     raise Exception("failed")
... 
&amp;gt;&amp;gt;&amp;gt; fail_fn()
Retry, exception: failed
Retry, exception: failed
Traceback (most recent call last):
  File "&amp;lt;stdin&amp;gt;", line 1, in &amp;lt;module&amp;gt;
  File "retry_decorator.py", line 32, in fn
    raise exception
Exception: failed
&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;gist.github.com&lt;/strong&gt; Repository: &lt;a href="http://gist.github.com/470611"&gt;http://gist.github.com/470611&lt;/a&gt;
&lt;/p&gt;
</content>
  </entry>
  <entry xml:base="http://peter-hoffmann.com/feed/atom.xml">
    <title type="text">Java 4-ever</title>
    <id>http://peter-hoffmann.com/2010/java-4-ever.html</id>
    <updated>2010-06-25T15:33:48Z</updated>
    <published>2010-06-25T15:33:48Z</published>
    <link href="http://peter-hoffmann.com/2010/java-4-ever.html" />
    <author>
      <name>Peter Hoffmann</name>
      <uri>http://peter-hoffmann.com</uri>
    </author>
    <content type="html">&lt;object width="640" height="385"&gt;&lt;param name="movie" value="http://www.youtube.com/v/KrfpnbGXL70&amp;hl=en_US&amp;fs=1&amp;"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/KrfpnbGXL70&amp;hl=en_US&amp;fs=1&amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="640" height="385"&gt;&lt;/embed&gt;&lt;/object&gt;
</content>
  </entry>
  <entry xml:base="http://peter-hoffmann.com/feed/atom.xml">
    <title type="text">This Week in Google with Chris Messina on OAuth and OpenID</title>
    <id>http://peter-hoffmann.com/2010/twig-chris-messina-oauth-openid.html</id>
    <updated>2010-06-17T12:32:26Z</updated>
    <published>2010-06-17T12:32:26Z</published>
    <link href="http://peter-hoffmann.com/2010/twig-chris-messina-oauth-openid.html" />
    <author>
      <name>Peter Hoffmann</name>
      <uri>http://peter-hoffmann.com</uri>
    </author>
    <content type="html">&lt;p&gt;
This Week in Google &lt;a href=""&gt;Episode 47&lt;/a&gt; with guest &lt;a
href="http://factoryjoe.com/"&gt;Chris Messina&lt;/a&gt; on OAuth an OpenID in an age
of "Facebook wants to own all your sign-ons". \via &lt;a href="http://smarterware.org/6281/this-week-in-google-episode-47"&gt;Gina Trapani&lt;/a&gt;
&lt;/p&gt;

&lt;object width="640" height="385"&gt;&lt;param name="movie" value="http://www.youtube.com/v/3GMfexcYk6U&amp;hl=en_US&amp;fs=1&amp;"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/3GMfexcYk6U&amp;hl=en_US&amp;fs=1&amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="640" height="385"&gt;&lt;/embed&gt;&lt;/object&gt;



</content>
  </entry>
  <entry xml:base="http://peter-hoffmann.com/feed/atom.xml">
    <title type="text">PubSubHubbub for JSON</title>
    <id>http://peter-hoffmann.com/2010/pubsubhubbub-for-json.html</id>
    <updated>2010-06-17T12:01:10Z</updated>
    <published>2010-06-17T12:01:10Z</published>
    <link href="http://peter-hoffmann.com/2010/pubsubhubbub-for-json.html" />
    <author>
      <name>Peter Hoffmann</name>
      <uri>http://peter-hoffmann.com</uri>
    </author>
    <content type="html">&lt;blockquote&gt;
Monica Keller (Facebook) und Martin Atkins (Six Apart) arbeiten an einer
JSON-Variante von pubsubhubbub. Besonders Facebook, deren OpenGraph-API
ausschließlich auf der JavaScript serialisierung basiert, scheint großes
Interesse an dem offenen Push-Protokoll zu haben. Schön dass der
Internet-Gigant sich die Mühe gibt, einen Standard voran zu treiben, anstatt
ein eigenes Format zu entwickeln. [via &lt;a
href="http://notizblog.org/2010/06/16/openweb-notizen-openid-safari-pubsubhubbub-microdata/"&gt;notizblog.org&lt;/a&gt;]
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://martin.atkins.me.uk/specs/pubsubhubbub-json" rel="bookmark"&gt;Spec: PubSubHubbub for JSON&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="http://groups.google.com/group/pubsubhubbub/browse_thread/thread/3fcadeef1683f563" rel="bookmark"&gt;Talk: PubSubHubbub for JSON&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</content>
  </entry>
  <entry xml:base="http://peter-hoffmann.com/feed/atom.xml">
    <title type="text">Using a namedtuple factory with python sqlite</title>
    <id>http://peter-hoffmann.com/2010/python-sqlite-namedtuple-factory.html</id>
    <updated>2010-06-08T10:56:41Z</updated>
    <published>2010-06-08T10:56:41Z</published>
    <link href="http://peter-hoffmann.com/2010/python-sqlite-namedtuple-factory.html" />
    <author>
      <name>Peter Hoffmann</name>
      <uri>http://peter-hoffmann.com</uri>
    </author>
    <content type="html">&lt;p&gt;
The python sqlite3 module ships with &lt;a
href="http://docs.python.org/library/sqlite3.html#sqlite3.Row"&gt;sqlite.Row&lt;/a&gt;,
a highly optimized row_factory. It supports mapping access by column name.
With python version 2.6 &lt;a
href="http://docs.python.org/dev/library/collections.html#collections.namedtuple"&gt;namedtuple&lt;/a&gt;
was added to the collections module. Namedtuples are used to create tuple-like
objects that have fields accessible by attribute lookup as well as being
indexable and iterable. So they are a perfect alternative for the sqlite.Row
factory;
&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
from collections import namedtuple

def namedtuple_factory(cursor, row):
    """
    Usage:
    con.row_factory = namedtuple_factory
    """
    fields = [col[0] for col in cursor.description]
    Row = namedtuple("Row", fields)
    return Row(*row)
&lt;/pre&gt;
Usage:
&lt;pre class="prettyprint"&gt;
&amp;gt;&amp;gt;&amp;gt; import sqlite3
&amp;gt;&amp;gt;&amp;gt; conn = sqlite3.connect(":memory:")
&amp;gt;&amp;gt;&amp;gt; c = conn.cursor()
&amp;gt;&amp;gt;&amp;gt; c.execute('''create table stocks
(date text, trans text, symbol text,
 qty real, price real)''')
&amp;lt;sqlite3.Cursor object at 0x8cf4d10&amp;gt;
&amp;gt;&amp;gt;&amp;gt; c.execute("""insert into stocks
          values ('2006-01-05','BUY','RHAT',100,35.14)""")
&amp;lt;sqlite3.Cursor object at 0x8cf4d10&amp;gt;
&amp;gt;&amp;gt;&amp;gt; conn.commit()
&amp;gt;&amp;gt;&amp;gt; c.close()
&amp;gt;&amp;gt;&amp;gt; conn.row_factory = namedtuple_factory
&amp;gt;&amp;gt;&amp;gt; c = conn.cursor()
&amp;gt;&amp;gt;&amp;gt; c.execute("select * from stocks")
&amp;lt;sqlite3.Cursor object at 0x8cf4d40&amp;gt;
&amp;gt;&amp;gt;&amp;gt; r = c.fetchone()
&amp;gt;&amp;gt;&amp;gt; type(r)
&amp;lt;class '__main__.Row'&amp;gt;
&amp;gt;&amp;gt;&amp;gt; r
Row(date=u'2006-01-05', trans=u'BUY', symbol=u'RHAT', qty=100.0, price=35.140000000000001)
&amp;gt;&amp;gt;&amp;gt; r.date
u'2006-01-05'
&amp;gt;&amp;gt;&amp;gt; for member in r:
...     print member
...     
2006-01-05
BUY
RHAT
100.0
35.14
&lt;/pre&gt;

</content>
  </entry>
</feed>
