Thanks Bruno, your comments were really helpful (so was the "improved" version of code).
My replies below: Bruno Desthuilliers wrote: >> So decorators inside of B just identify that those methods will be >> proxied by A. On one hand from logical standpoint it's kind of weird to >> tell class that it is going to be proxied by another class, > > Indeed - usually, proxied objects shouldn't have to be aware of the > fact. That doesn't mean your variation on the proxy pattern is > necessarily bad design (hard to tell without lot of context anyway...), > but still there's some alarm bell ringing here IMHO - IOW : possibly the > right thing to do, but needs to be double-checked. I'm kind of looking at options and not dead-set on decorators, but I can't find any other "elegant enough" solution which wouldn't lead to such tight coupling. The problem I'm trying to solve is not much more complicated than what I have already described so if anybody can suggest a better approach - I'm all for it. > Now I'm not sure I really like your implementation. Here's a possible > rewrite using a custom descriptor: yeah, that was going to be my next step - I was just aiming for proof-of-concept more then efficient code :) > class Proxymaker(object): > def __init__(self, attrname): > self.attrname = attrname > > def __get__(self, instance, cls): > def _proxied(fn): > fn_name = fn.__name__ > def delegate(inst, *args, **kw): > target = getattr(inst, self.attrname) > #return fn(target, *args,**kw) > method = getattr(target, fn_name) > return method(*args, **kw) > > delegate.__name__ = "%s_%s_delegate" % \ > (self.attrname, fn_name) > > setattr(cls, fn_name, delegate) > return fn > > return _proxied > > class A(object): > def __init__(self,b): > self.val='aval' > self.b=b > b.val='aval' > > proxy2b = Proxymaker('b') > > def mymethod(self,a): > print "A::mymethod, ",a > > def mymethod2(self,a): > print "A::another method, ",a > > class B(object): > def __init__(self): > self.val='bval' > > @A.proxy2b > def bmethod(self,a): > print "B::bmethod" > print a, self.val > > @A.proxy2b > def bmethod2(self,a): > print "B::bmethod2" > print a, self.val > My point is that: > 1/ you shouldn't have to rewrite a decorator function - with basically > the same code - for each possible proxy class / attribute name pair combo > 2/ making the decorator an attribute of the proxy class makes > dependencies clearer (well, IMHO at least). agreed on all points > I'm still a bit uneasy wrt/ high coupling between A and B, and if I was > to end up with such a design, I'd probably take some times to be sure > it's really ok. that is the question that troubles me at this point - thus my original post (read the subject line ;) ). I like the clarity decorators bring to the code and the fact that it's a solution pretty much "out-of-the-box" without need to create something really-really custom, but I'm worried about tight coupling and somewhat backward logic that they would introduce (the way I envisioned them). -- http://mail.python.org/mailman/listinfo/python-list