How do I do this without class methods ?

Remco Gerlich scarblac at pino.selwerd.nl
Wed May 2 12:49:27 EDT 2001


Jacek Generowicz <jmg at ecs.soton.ac.uk> wrote in comp.lang.python:
> Jacek Generowicz <jmg at ecs.soton.ac.uk> writes:
> 
> > (Full version performing to spec. below . . .)
> > 
> > -----------------------------------------------------------
> > 
> > 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 ?

Cache it? No reason why __getattr__ can't set some cache and check it.

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

This is how I would do it. I've taken your "horrible but functioning
solution 2" and added a klass argument to it. Also, the polygon implements
the caching automatically, by keeping its own copy of N, to check if the
cache needs updating (this uses __getattr__).

import math

class polygon:
   def __init__(self, size):
      self.radius = size # Unused I think, but kept because you had it
      self._N_cache = None
   def __getattr__(self, arg):
      if arg != 'area':
      	 raise AttributeError, "class polygon has no attribute '%s'" % (arg,)
      if self._N_cache != self.__class__.N:
         self._N_cache = self.__class__.N
	 self._area_cache = N * math.sin(2 * math.pi / N)
      return self._area_cache
   def use_instance(self, coefficient):
      return self.area * coefficient

def set_parameter(klass, N):
   klass.N = N


> # Trivial example of usage

def use_polygons(coeff):
   # Create some instances
   lots_of_instances = map(polygon, range(1,3))
   # Use the instances
   for instance in lots_of_instances:
      print instance.use_instance(coeff)
   print
   
set_parameter(polygon, N=4) # No need for the named argument but I like it
use_polygons(1)

> Class methods would make this all so simple :-)
> 
> Any edifying comments or suggestions ?

I suppose I failed to understand something? Why would the class method look
any different (I imagine the class method solution would be identical except
the set_parameter function would be indented a level more...).

-- 
Remco Gerlich



More information about the Python-list mailing list