Read-only Python Attributes

10 AM June 3, 2004

Property descriptors are a powerful tool for building easy to understand APIs. I use read-only properties liberally in my APIs, but it took a few months to arrive at an implementation idiom that I was happy with.

In Kangapy,1 each article is associated with a template, and the template may not change after the article object is constructed. It makes sense for the Article class to have a read-only 'template' attribute.

Based on what I had read of property descriptors, this was my first version of the descriptor code:


  def __getTemplate(self):

      return self.__template

  template = property(__getTemplate, None, None, 

          "This article's defining Template") 

While it provides a neat API for getting the article's template, the implementation is long winded and difficult to read. Compare it with the implementation of the equivalent getter method:


  def getTemplate(self):

      """ This article's defining Template

      """

      return self.__template

Casting around for a better way to write property descriptors, I hit on a methodless idiom that I am still using:


  template = property(lambda self: self.__template) 

Simple derived value properties also work well:


  templateName = property(lambda self: self.__template.name) 

This methodless form of a property is simpler to write and read than the original form. On the down side, it doesn't have a doc string,2 and it still isn't as clear as a getter method.


1 Kangapy is my blogging software. It is currently undergoing its third complete rewrite. After this one, I'll release the source, I promise.

2 I found that burying the doc string inside the property function meant that I wasn't using it while I was editing the code. Since I'm not using pydoc, the doc string was useless.

By alang | # | Comments (7)
(Posted to Python)
© 2003-2006 Alan Green