How do I do this without class methods ?

Jacek Generowicz jmg at ecs.soton.ac.uk
Wed May 2 12:02:28 EDT 2001


Jacek Generowicz <jmg at ecs.soton.ac.uk> writes:

> Jacek Generowicz <jmg at ecs.soton.ac.uk> writes:

<snip>

> > class woderwick:
> >     bwian = [ 'zero', 'one', 'two', 'many' ]
> >     _wodger_index = 0 # default
> >     def __getattr__ ( self, name ):
> >         if name == 'wodger':
> >             return self.bwian[self._wodger_index]
> 
> What should I do if the operation which is to be performed here is
> very expensive, and hence should only be performed once and cached for
> future use ?

<snip>

> I've invented a different example, which more closely reflects what I
> need. Unfortuanately, with all the alternatives and comments, it has
> turned out a little longer that I would like . . . sorry.

<Example snipped>

OK, I've found an interesting solution to the problem: Alex'
static-methods recipe . . . but it does seem to mess up inheritance
somewhat, by having to replace self._class__.unit_area with the more
explicit and specific polygon.unit_area in polygon.set_class_cache.
Is there a way of improving on this ?

Modified example code stripped down to bare essentials follows:

# http://www.activestate.com/ASPN/Python/Cookbook/Recipe/52304
class Callable:
    def __init__(self, anycallable):
        self.thecallable = anycallable
    def __call__(self, *args, **kwds):
        return self.thecallable(*args, **kwds)

import math

# (A hierarchy of) objects whose behaviour changes as a function of a
# globally settable parameter
class polygon:
    def __init__ ( self, size ):
        self.radius = size
        
    def set_class_cache ( N ):
	# The next line had to be changed
	# self.__class__.unit_area = N * math.sin( 2 * math.pi / N ) 
        polygon.unit_area = N * math.sin( 2 * math.pi / N ) 
    # Make it static
    set_class_cache = Callable(set_class_cache)
    
    def set_instance_cache ( self ):
        self.area = self.radius * self.unit_area 

    def use_instance ( self, coefficient ):
        return self.area * coefficient

def set_parameter_ideal ( klass, N ):
    klass.set_class_cache( N )

def use_polygons ( coeff ):
    lots_of_instances = map( polygon, range( 1,3 ) )
    for instance in lots_of_instances:
        instance.set_instance_cache()
    for instance in lots_of_instances:
        print instance.use_instance( coeff )
    print


# Now it does work
set_parameter_ideal( polygon, 3 )
use_polygons( 2 )




More information about the Python-list mailing list