473,394 Members | 1,869 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,394 software developers and data experts.

Re: decorator and API

Lee Harr wrote:
I have a class with certain methods from which I want to select
one at random, with weighting.

The way I have done it is this ....

import random

def weight(value):
def set_weight(method):
method.weight = value
return method
return set_weight

class A(object):
def actions(self):
'return a list of possible actions'

return [getattr(self, method)
for method in dir(self)
if method.startswith('action_')]

def action(self):
'Select a possible action using weighted choice'

actions = self.actions()
weights = [method.weight for method in actions]
total = sum(weights)

choice = random.randrange(total)

while choiceweights[0]:
choice -= weights[0]
weights.pop(0)
actions.pop(0)

return actions[0]
@weight(10)
def action_1(self):
print "A.action_1"

@weight(20)
def action_2(self):
print "A.action_2"
a = A()
a.action()()


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.
Here is another approach:

8<-------------------------------------------------------------------

import random
from bisect import bisect

#by George Sakkis
def take_random_action(obj, actions, weights):
total = float(sum(weights))
cum_norm_weights = [0.0]*len(weights)
for i in xrange(len(weights)):
cum_norm_weights[i] = cum_norm_weights[i-1] + weights[i]/total
return actions[bisect(cum_norm_weights, random.random())](obj)

class randomiser(object):

_cache = []

@classmethod
def alert(cls, func):
assert hasattr(func, 'weight')
cls._cache.append(func)

@classmethod
def register(cls, name, obj):
actions = {}
weights = []
for klass in obj.__class__.__mro__:
for val in klass.__dict__.itervalues():
if hasattr(val, '__name__'):
key = val.__name__
if key in actions:
continue
elif val in cls._cache:
actions[key] = val
weights.append(val.weight)
actions = actions.values()
#setattr(cls, name, classmethod(lambda cls:
random.choice(actions)(obj)))
setattr(cls, name, classmethod(lambda cls:
take_random_action(obj, actions, weights)))

def randomised(weight):
def wrapper(func):
func.weight = weight
randomiser.alert(func)
return func
return wrapper

class A(object):

@randomised(20)
def foo(self):
print 'foo'

@randomised(10)
def bar(self):
print 'bar'

class B(A):

@randomised(50)
def foo(self):
print 'foo'

8<-------------------------------------------------------------------

randomiser.register('a', A())
randomiser.register('b', B())
print 'A'
randomiser.a()
randomiser.a()
randomiser.a()
randomiser.a()
randomiser.a()
randomiser.a()
print 'B'
randomiser.b()
randomiser.b()
randomiser.b()
randomiser.b()
randomiser.b()
randomiser.b()
Sep 18 '08 #1
0 662

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

11
by: Ville Vainio | last post by:
It might just be that @decorator might not be all that bad. When you look at code that uses it it's not that ugly after all. A lot of the furor about this is probably because it happened so...
41
by: John Marshall | last post by:
How about the following, which I am almost positive has not been suggested: ----- class Klass: def __init__(self, name): self.name = name deco meth0: staticmethod def meth0(x):
17
by: Jim Jewett | last post by:
Guido has said that he is open to considering *one* alternative decorator syntax. At the moment, (Phillip Eby's suggestion) J4 <URL: http://www.python.org/moin/PythonDecorators > (section 5.21...
30
by: Ron_Adam | last post by:
I was having some difficulty figuring out just what was going on with decorators. So after a considerable amount of experimenting I was able to take one apart in a way. It required me to take a...
22
by: Ron_Adam | last post by:
Hi, Thanks again for all the helping me understand the details of decorators. I put together a class to create decorators that could make them a lot easier to use. It still has a few glitches...
3
by: Ron_Adam | last post by:
Ok... it's works! :) So what do you think? Look at the last stacked example, it process the preprocess's first in forward order, then does the postprocess's in reverse order. Which might be...
6
by: Michele Simionato | last post by:
could ildg wrote: > I think decorator is a function which return a function, is this right? > e.g. The decorator below if from http://www.python.org/peps/pep-0318.html#id1. > > def...
5
by: Doug | last post by:
I am looking at using the decorator pattern to create a rudimentary stored proc generator but am unsure about something. For each class that identifies a part of the stored proc, what if I want to...
4
by: thomas.karolski | last post by:
Hi, I would like to create a Decorator metaclass, which automatically turns a class which inherits from the "Decorator" type into a decorator. A decorator in this case, is simply a class which...
8
by: Chris Forone | last post by:
hello group, is there a possibility to implement the decorator-pattern without new/delete (nor smartpt)? if not, how to ensure correct deletion of the objects? thanks & hand, chris
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.