Automatic methods in new-style classes

George Sakkis george.sakkis at gmail.com
Fri Sep 29 21:57:20 EDT 2006


Ben Cartwright wrote:

> bertgoos at yahoo.com wrote:
> > Hey, I have the following code that has to send every command it
> > receives to a list of backends.
> <snip>
> > I would like to write each method like:
> >
> >     flush = multimethod()
>
> Here's one way, using a metaclass:

Or if you don't mind a more verbose API, you may use a decorator
instead:

# comment out if version<2.5
from functools import wraps

def do_forall(attr):
    def deco(func):
        f_name = func.__name__
        @wraps(func) # comment out if version<2.5
        def wrapper(self,*args,**kwds):
            for b in getattr(self,attr):
                getattr(b,f_name)(*args,**kwds)
        return wrapper
    return deco

#====== Example =================================

class Foo(object):
    def flush(self): print "Foo.flush"
    def draw(self, x, y): print "Foo.draw(%s,%s)" % (x,y)

class Bar(object):
    def flush(self): print "Bar.flush"
    def draw(self, x, y): print "Bar.draw(%s,%s)" % (x,y)


forall_backends = do_forall('backends')

class MultiBackend(object):
    """Renders to multiple backends"""

    def __init__(self, backends):
        self.backends = backends

    @forall_backends
    def flush(self):
        'Flush all backends'

    @forall_backends
    def draw(self, x, y):
        'Draw point (x,y) on all backends'


m = MultiBackend([Foo(),Bar()])
m.flush()
m.draw(1,2)

#======================================

HTH,
George




More information about the Python-list mailing list