On Sep 25, 1:22 pm, "Dmitry S. Makovey" <[EMAIL PROTECTED]> wrote: > Aaron "Castironpi" Brady wrote: > > You should write it like this: > > > class B(object): > > [EMAIL PROTECTED] > > def bmethod(self,a): > > > Making 'proxy' a class method on A. > > makes sense. > > > In case different A instances (do > > you have more than one BTW?) > > yep. I have multiple instances of class A, each one has properties (one per > class) of classes B, C and D: > > class A: > b=None > c=None > d=None > def __init__(self,b,c,d): > self.b=b > self.c=c > self.d=d > > ...magic with proxying methods goes here... > > class B: > def bmethod(self,x): pass # we proxy this method from A > def bmethod2(self,x): pass # this is not proxied > class C: > def cmethod(self,x): pass # we proxy this method from A > class D: > def dmethod(self,x): pass # we proxy this method from A > > a=A(B(),C(),D()) > x='foo' > a.bmethod(x) > a.cmethod(x) > a.dmethod(x) > a.bmethod2(x) # raises error as we shouldn't proxy bmethod2 > > above is the ideal scenario. > > > What you've said implies that you only have one B instance, or only > > one per A instance. Is this correct? > > yes. as per above code. > > > I agree that __setattr__ is the canonical solution to proxy, but you > > have stated that you want each proxied method to be a member in the > > proxy class. > > well. kind of. if I can make it transparent to the consumer so that he > shouldn't do: > > a.b.bmethod(x) > > but rather: > > a.bmethod(x) > > As I'm trying to keep b, c and d as private properties and would like to > filter which calls are allowed to those. Plus proxied methods in either one > always expect certain parameters like: > > class B: > def bmethod(self,c,x): pass > > and A encapsulates 'c' already and can fill in that blank automagically: > > class A: > c=None > b=None > def bmethod(self,c,x): > if not c: > c=self.c > b.bmethod(self,c,x) > > I kept this part of the problem out of this discussion as I'm pretty sure I > can fill those in once I figure out the basic problem of auto-population of > proxy methods since for each class/method those are going to be nearly > identical. If I can autogenerate those on-the-fly I'm pretty sure I can add > some extra-logic to them as well including signature change where > A::bmethod(self,c,x) would become A::bmethod(self,x) etc.
Do you want to couple instances or classes together? If A always proxies for B, C, and D, then the wrapper solution isn't bad. If you're going to be doing any instance magic, that can change the solution a little bit. There's also a revision of the first implementation of Aproxy you posted, which could stand alone as you have it, or work as a classmethod or staticmethod. > def Aproxy(fn): > def delegate(*args,**kw): > print "%s::%s" % (args[0].__class__.__name__,fn.__name__) > args=list(args) > b=getattr(args[0],'b') > fnew=getattr(b,fn.__name__) > # get rid of original object reference > del args[0] > fnew(*args,**kw) > setattr(A,fn.__name__,delegate) > return fn def Aproxy(fn): def delegate(self,*args,**kw): print "%s::%s" % (args[0].__class__.__name__,fn.__name__) fnew=getattr(self.b,fn.__name__) return fnew(*args,**kw) setattr(A,fn.__name__,delegate) return fn -- http://mail.python.org/mailman/listinfo/python-list