Descriptors and side effects

Rich Harkins rich at worldsinfinite.com
Mon Nov 5 12:40:54 EST 2007


Bruno Desthuilliers wrote:
[snip]
> I'm sorry, but this looks like a very complicated way to do a simple thing:
> 
> class MySimpleClass(object):
>    def __init__(self, x):
>      self.x = x
>      self.y = x ** 2
> 
> 

Sure, for the absurdly simplified case I posed as an example.  ;)

Here's another:

class Path(tuple):
    @ConstProperty
    def pathstr(self):
        print "DEBUG: Generating string"
        return '/'.join(self)

    def __add__(self, other):
        if isinstance(other, tuple):
             return Path(tuple.__add__(self, other))
        else:
             return Path(tuple.__add__(self, (other,)))

>>> ROOT = Path(())
>>> path = ROOT + 'x' + 'y' + 'z'
>>> path.pathstr
DEBUG: Generating string
/x/y/z
>>> path.pathstr
/x/y/z

Basically, you can use ConstProperty above for items you don't want to
calculate automatically, but only when someone actually WANTS it.  After
it is applied, then the penalties for function call of the property and
the computation are wiped out once the second access is requested.

Now, in the original example, len() might be considered too little for
this use and should be just generated in the constructor "for free".
OTOH, that assumes that __len__ hasn't been overridden to do something
more complicated and time consuming.  If the antecedent object is
static, and the derivative consequent is also static, then ConstProperty
works very well and shouldn't cost more on the first access than any
other built-in property function.

BTW, another use is to avoid creating lots of unnecessary objects for
free unless they are accessed.  Another quickie example:

class Node(object):
    hasChildList = False
    hasAttributesDict = False

    @ConstProperty
    def children(self):
        self.hasChildList = True
        return []

    @ConstProperty
    def attributes(self):
        self.hasAttributesDict = True
        return {}

The extra class/object attributes can be used to test for whether the
associated objects were created.  When used in a large tree, not
creating a lot of extra lists and dictionaries can save a lot of memory
and CPU as the children and attributes are not created or explored
unless they were manipulated.

Rich



More information about the Python-list mailing list