Dmitry S. Makovey a écrit :
Aaron "Castironpi" Brady wrote:
It might help to tell us the order of events that you want in your
program.  You're not using 'mymethod' or 'mymethod2', and you probably
want 'return fnew' for the future.  Something dynamic with __getattr__
might work.  Any method call to A, that is an A instance, tries to
look up a method of the same name in the B instance it was initialized
with.

well 'mymethod' and 'mymethod2' were there just to show that A doesn't
function as a pure proxy - it has methods of it's own. See my respnse to
Steve - I proxy messages to more than one aggregated object. going over
them on __getattr__ to look up methods just doesn't seem to be really
efficient to me (I might be wrong though). Decorators seemed to present
good opportunity to simplify the code (well except for the decorator
function itself :) ), make code bit more "fool-proofed" (and give me the
opportunity to test decorators in real life, he-he).

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.

but declaration would be
real close to original function definition which helps to identify where is
it used.

Note that my decorator doesn't change original function - it's a subversion
of decorator to a certain degree as I'm just hooking into python machinery
to add methods to A upon their declaration in B (or so I think).

I wouldn't call this a "subversion" of decorators - it's even a pretty common idiom to use decorators to flag some functions/methods for special use.

Now I'm not sure I really like your implementation. Here's a possible rewrite using a custom descriptor:

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).

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.

My  cents...
--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to