Properties - when and why

Alex Martelli aleax at aleax.it
Mon Jul 8 02:36:39 EDT 2002


Arthur Siegel wrote:

> Learning something about properties - as usual the hard way.
> Beginning to conclude that they, as I recently learned with __slots__,
> are more "special case" than I first understood.

Maybe, but I don't think the following example indicates that.
It seems a perfectly normal and general case.


> Say self.W and self.U are each 3 element vectors referenced on
> initialization, with attributes x,y, z. V is a calculated vector.  V=W-U
> 
> def get_V(self):
>    return self.W-self.U
> 
> V=properties(get_V)

Presumably 'property', but OK, so far so good.  Each time you
access foo.V, this induces a call to foo.W.__sub__(foo.U).  OK.


> But occasionally I need to access V's attributes individually.

Sure, it happens.

> def V_homogenous(self):
>     return array((V.x,V.y,V.z,1.))

That, of course, doesn't work -- what's that "V"?  Must be
some global variable, and has no relation with method get_V.
I'll assume you mean self.V here...

> Have I not just made three calls to the vector subtraction
> of the get_V method? Not good.

Why not?  As far as any of us know so far, and as far as Python
knows, each call to self.W.__sub__(self.U) may return a completely
different result.  So, when you specify three calls, you get
three calls.  Nothing "special case" about this -- Python NEVER
optimizes multiple calls down to one call, nor does it ever do
any "common subexpression elimination".  If you need such things
to happen, you just specify them yourself.


> Could have done:
> def get_V(self):
>    self._V  = self.W - self.V
>    return self._V
> 
> def V_homogenous(self):
>     return array((self._V.x,self._V.y,self._V.z,1.))

Now THAT would be outright silly -- with no guarantee in the
body of V_homogeneous that get_V has ever been called and this
that self._V has any relation with reality!

The obvious solution for this case is to keep your original
get_V method intact and to code V_homogeneous the simple way:

def V_homogenous(self):
    V = self.V
    return array((V.x,V.y,V.z,1.))

Seriously, what COULD be simpler -- or, less special-case...?!

> Is the when and why of using properties something that can be
> explained in few enough words?

Use properties when you want the syntax of attribute access
and the semantics of a method call.  That has nothing to do
with the fact that if you need "common subexpression elimination"
you need to write that out explicitly -- Python never eliminates
common subexpressions by itself.


Alex




More information about the Python-list mailing list