[Python-Dev] RFC: readproperty (original) (raw)

Guido van Rossum guido at python.org
Wed Sep 28 16:47:26 CEST 2005


On 9/28/05, Jim Fulton <jim at zope.com> wrote:

Read descriptors (defining only get) and data descripttors have (defining get and set) different semantics. In particular, read descriptors are overridden by instance data, while data descriptors are not. A common use of read descriptors is for lazily computed data:

class readproperty(object): "Create a read descriptor from a function" def init(self, func): self.func = func def get(self, inst, class): if inst is None: return self return self.func(inst) class Spam: @readproperty def eggs(self): ... expensive computation of eggs self.eggs = result return result When we ask for the eggs attribute the first time, we call the descriptor, which calls the eggs function. The function sets the eggs attribute, overriding the descriptor. The next time the eggs attribute is accessed, the saved value will be used without calling the descriptor. I do this often enough that I think it would be useful to include it in python, either as a builtin (like property) or in the library. (Or possibly by adding an option to property to generate a read descriptor.) I'd be happy to add this for 2.5. Thoughts?

I like the idea of adding this functionality somewhere. I do note that the semantics were somewhat of an accident, required by backwards compatibility with pre-2.2 method lookup semantics.

I think we need to be real careful with chosing a name -- in Jim's example, anyone could assign to Spam().eggs to override the value. The name "readproperty" is too close to "readonlyproperty", but read-only it ain't! "Lazy" also doesn't really describe what's going on.

I believe some folks use a concept of "memo functions" which resemble this proposal except the notation is different: IIRC a memo function is always invoked as a function, but stores its result in a private instance variable, which it returns upon subsequent calls. This is a common pattern. Jim's proposal differs because the access looks like an attribute, not a method call. Still, perhaps memoproperty would be a possible name.

Another way to look at the naming problem is to recognize that the provided function really computes a default value if the attribute isn't already set. So perhaps defaultproperty?

(Sorry to turn this into a naming game, which is bound to produce 100s of competing proposals that are totally unintuitive except to the proposer. But naming is important.)

-- --Guido van Rossum (home page: http://www.python.org/~guido/)



More information about the Python-Dev mailing list