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 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 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
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 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
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
The metaclass approach seems to be the one I was looking for. Thanks!
Bert This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
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...
|
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...
|
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...
|
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...
|
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...
|
by: edd |
last post by:
Hello all,
Please consider:
template<typename Tclass my_class;
template<class my_class<int>
{
//...
};
|
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...
|
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...
|
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)...
|
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...
|
by: Charles Arthur |
last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
|
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
|
by: nemocccc |
last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
|
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...
|
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,...
|
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...
|
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...
|
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: 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...
| |