Descriptors and side effects

Bruno Desthuilliers bdesth.quelquechose at free.quelquepart.fr
Mon Nov 5 15:02:39 EST 2007


Rich Harkins a écrit :
> 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):

Ok, for an immutable type, it might eventually work.

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

import os.path
help(os.path)

>     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

 >>> p = Path(('home', 'bruno'))
 >>> p += ['toto', 'tata']
 >>> p.pathstr
DEBUG: Generating string
Traceback (most recent call last):
   File "<stdin>", line 1, in ?
   File "/usr/tmp/python-8690chu", line 31, in __get__
   File "/usr/tmp/python-8690chu", line 40, in pathstr
TypeError: sequence item 2: expected string, list found
 >>>


> Basically, you can use ConstProperty above for items you don't want to
> calculate automatically, but only when someone actually WANTS it.

Which is easy to do with properties too.

>  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.

Agreed. But I wouldn't use such a scheme for mutable types - which are 
still the common case.

> 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,

You mean 'immutable', I assume...

> 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 {}

Hmm... Perhaps not such a bad idea after all !-)



More information about the Python-list mailing list