Automatic methods in new-style classes

Ben Cartwright bencvt at gmail.com
Fri Sep 29 18:23:10 EDT 2006


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:

class multimethod(object):
    def transform(self, attr):
        def dispatch(self, *args, **kw):
            results = []
            for b in self.backends:
                results.append(getattr(b, attr)(*args, **kw))
            return results
        return dispatch

def multimethodmeta(name, bases, dict):
    """Transform each multimethod object into an actual method"""
    for attr in dict:
        if isinstance(dict[attr], multimethod):
            dict[attr] = dict[attr].transform(attr)
    return type(name, bases, dict)

class MultiBackend(object):
    __metaclass__ = multimethodmeta
    def __init__(self, backends):
        self.backends = backends
    add = multimethod()

class Foo(object):
    def add(self, x, y):
        print 'in Foo.add'
        return x + y

class Bar(object):
    def add(self, x, y):
        print 'in Bar.add'
        return str(x) + str(y)

m = MultiBackend([Foo(), Bar()])
print m.add(3, 4)

# Output:
in Foo.add
in Bar.add
[7, '34']

--Ben




More information about the Python-list mailing list