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.