473,406 Members | 2,549 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,406 software developers and data experts.

Automatic methods in new-style classes

Hey, I have the following code that has to send every command it
receives to a list of backends. Instead of:

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

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

def flush(self):
for b in self.backends:
b.flush()

def draw(self):
for b in self.backends:
b.draw()
I would like to write each method like:

flush = multimethod()

Is that possible using new-style classes?

Bert

Sep 29 '06 #1
6 1271
be******@yahoo.com wrote:
Hey, I have the following code that has to send every command it
receives to a list of backends. Instead of:

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

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

def flush(self):
for b in self.backends:
b.flush()

def draw(self):
for b in self.backends:
b.draw()
I would like to write each method like:

flush = multimethod()

Is that possible using new-style classes?
Not without a custom metaclass or the method name passed explicitly to
multimethod(). Here's a simpler approach that works with both new and
classic classes:

"""
>>class B(object):
.... def __init__(self, name):
.... self.name = name
.... def draw(self, x, y):
.... print "%s: draw(%s, %s)" % (self.name, x, y)
.... def flush(self):
.... print "%s: flush()" % self.name
>>m = MultiBackend([B("alpha"), B("beta")])
m.draw(1, 2)
alpha: draw(1, 2)
beta: draw(1, 2)
>>m.flush()
alpha: flush()
beta: flush()

"""

from operator import attrgetter

class MultiBackend(object):
def __init__(self, backends):
self._backends = backends
def __getattr__(self, name):
get = attrgetter(name)
def multi(self, *args, **kw):
for b in self._backends:
get(b)(*args, **kw)
setattr(self.__class__, name, multi)
return getattr(self, name)

if __name__ == "__main__":
import doctest
doctest.testmod()

Peter
Sep 29 '06 #2
be******@yahoo.com wrote:
Hey, I want to send commands to a list of backends:
How about something like:
class Forwards(object):

to_forward = set(['flush', 'read', 'write', 'close'])

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

def forwarder(self, methodname):
def method(*args, **kwargs):
for b in self.backends:
getattr(b, methodname)(*args, **kwargs)
return forwarder

def __getattr__(self, name):
if name in self.to_forward:
return self.forwarder(name)
raise AttributeError("%r object has no attribute %r"
% (self.__class__.__name__, name))

--Scott David Daniels
sc***********@acm.org
Sep 29 '06 #3
Scott David Daniels wrote:
>
class Forwards(object):

to_forward = set(['flush', 'read', 'write', 'close'])

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

def forwarder(self, methodname):
def method(*args, **kwargs):
for b in self.backends:
getattr(b, methodname)(*args, **kwargs)
return forwarder
^^^ return method # thinko.
>
def __getattr__(self, name):
if name in self.to_forward:
return self.forwarder(name)
raise AttributeError("%r object has no attribute %r"
% (self.__class__.__name__, name))
--Scott David Daniels
sc***********@acm.org
Sep 29 '06 #4
be******@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

Sep 29 '06 #5
Ben Cartwright wrote:
be******@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

Sep 30 '06 #6
The metaclass approach seems to be the one I was looking for. Thanks!

Bert

Sep 30 '06 #7

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

Similar topics

0
by: David Burson | last post by:
Hi, I have a VB.NET windows app that needs to automatically send a simple text email when my users run a new version of the app for the first time. I thought this would be simple, but after...
15
by: Kannan Goundan | last post by:
Maintaining a C++ header file can be painful. I want a way to automatically generate header files from the implementation file. Does anybody know of a program that does this? If not, I'd like...
5
by: Shane | last post by:
I wonder if someone has any ideas about the following. I am currently producing some reports for a manufacturing company who work with metal. A finished part can contain multiple sub-parts to...
3
by: Tom | last post by:
Using AccessXP with WindowsXP. I am creating a new database in Access2000 mode. The list of methods does not come up when I type a dot after a control in code. What do I need to do to turn that...
1
by: Michel Esber | last post by:
Hello, Linux RedHat AS4 running DB2 V8 FP11. I have followed the docs at http://tinyurl.com/qckrn and enabled automatic statistics collection. It has been 2 days since I updated my DB cfg and...
5
by: edd | last post by:
Hello all, Please consider: template<typename Tclass my_class; template<class my_class<int> { //... };
1
by: dev | last post by:
Hello, In VS2005, we have a WebService project (WSE) and a WebSite project (WSI) that uses WSE (we added the reference in the App_WebReferences of the WSI project) Is it possible to have the...
0
by: JoshforRefugee | last post by:
heard that we can do automatic code generation using macros, but not sure how can I pursue this. Here is my problem. In my env, I have class A,B and C. All of them has constructors, and few...
9
by: andrewfelch | last post by:
Hello all, I'm using the metaclass trick for automatic reloading of class member functions, found at: http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/160164 My problem is that if I 1)...
3
by: myjish18 | last post by:
Hello, We have a DB2 UDB database v8.2.7 (db2 v8.2 fixpak 14) on AIX 5.3 which has Automatic Storage (AS) enabled. We want to disable automatic storage on entire database and/or disable...
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
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
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
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
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...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

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.