On Sep 17, 6:09 pm, "Aaron \"Castironpi\" Brady" <[EMAIL PROTECTED]> wrote: > On Sep 17, 4:56 pm, Lee Harr <[EMAIL PROTECTED]> wrote: > > > > > I have a class with certain methods from which I want to select > > one at random, with weighting. (snip) > > > The problem I have now is that if I subclass A and want to > > change the weighting of one of the methods, I am not sure > > how to do that. > > > One idea I had was to override the method using the new > > weight in the decorator, and then call the original method: > > > class B(A): > > @weight(50) > > def action_1(self): > > A.action_1(self) > > > That works, but it feels messy. > > > Another idea was to store the weightings as a dictionary > > on each instance, but I could not see how to update that > > from a decorator. > > > I like the idea of having the weights in a dictionary, so I > > am looking for a better API, or a way to re-weight the > > methods using a decorator. > > > Any suggestions appreciated. > > class A: > weights= WeightOb() #just a dictionary, mostly > [EMAIL PROTECTED]( 10 ) ... > [EMAIL PROTECTED]( 20 ) ... > > class B( A ): > weights= WeightOb( A.weights ) #new, refs "super-member" > [EMAIL PROTECTED]( 50 ) ...
Lee, Probably overkill. Here's a solution like above. class WeightOb( object ): def __init__( self, *supers ): self.weights= {} self.supers= supers def set( self, weight ): def __callset__( fun ): self.weights[ fun.func_name ]= weight return fun return __callset__ def reset( self, weight, fun ): self.weights[ fun.func_name ]= weight return fun #search parent 'weight' objects #return 'child-most' weight of 'name' def get_weight( self, name ): if name in self.weights: return self.weights[ name ] else: for x in self.supers: try: return x.get_weight( name ) except KeyError: #not found pass raise KeyError #returns a dictionary mapping bound instances to weights #(hence the second parameter) def contents( self, inst ): d= {} for x in reversed( self.supers ): d.update( x.contents( inst ) ) d.update( dict( [ ( getattr( inst, k ), v ) for k, v in self.weights.iteritems( ) ] ) ) return d class A( object ): weights= WeightOb( ) @weights.set( 10 ) def action_1( self ): print 'action_1' @weights.set( 20 ) def action_2( self ): print 'action_2' #WeightOb.contents needs to know which instance to bind #functions to. Get weights from an instance that has them. def getweights( self ): return self.weights.contents( self ) class B( A ): weights= WeightOb( A.weights ) action_2= weights.reset( 50, A.action_2 ) a= A() b= B() print a.weights.get_weight( 'action_1' ) print a.weights.get_weight( 'action_2' ) print b.weights.get_weight( 'action_1' ) print b.weights.get_weight( 'action_2' ) print a.getweights( ) print b.getweights( ) /Output: 10 20 10 50 {<bound method A.action_2 of <__main__.A object at 0x00A04070>>: 20, <bound meth od A.action_1 of <__main__.A object at 0x00A04070>>: 10} {<bound method B.action_2 of <__main__.B object at 0x00A04090>>: 50, <bound meth od B.action_1 of <__main__.B object at 0x00A04090>>: 10} -- http://mail.python.org/mailman/listinfo/python-list