Delegating method call by condition

Something that might challenge most of the users on the forum? Post it here.

Moderators: KDoiron, ChrJim, mawe, python

Delegating method call by condition

Postby Azurin on Sun Feb 28, 2010 9:18 am

Hi,
Imagine we have the following:
Code: Select all
class A(object):
    def m1(self):
        pass
    def m2(self):
        pass

class B(object):
    def __init__(self):
        self.a = A()

What I need is to be able to call either A methods or B methods through B instance.
Smth like
Code: Select all
def __getattribute__(self, name): # B method call
    if condition:
        # try call method from self.a
    else:
        # try call method from self

Hope I described clearly..
Azurin
Python Fan
Python Fan
 
Posts: 4
Joined: Sun Feb 28, 2010 8:53 am

Re: Delegating method call by condition

Postby targ on Tue Mar 02, 2010 1:55 am

Code: Select all
def __getattribute__(self, name):
    return object.__getattribute__(self.a if condition else self, name)
Does that work?
targ
Python Heavy Programmer
Python Heavy Programmer
 
Posts: 225
Joined: Tue Apr 07, 2009 2:54 pm

Re: Delegating method call by condition

Postby Azurin on Tue Mar 02, 2010 2:29 pm

targ,

The problem is, that when you try to access some member via self in __getattribute__ method it is instantly executed, and thus going to "endless" recursion.
Azurin
Python Fan
Python Fan
 
Posts: 4
Joined: Sun Feb 28, 2010 8:53 am

Re: Delegating method call by condition

Postby targ on Tue Mar 02, 2010 2:56 pm

Yes, that's why I use object.__getattribute__(self, name) instead of self.__getattribute__(name).

The __getattribute__ method (or any method) of a superclass (object in this case) will not be affected by any of its subclasses' definitions of the same method, so it's safe to use.
targ
Python Heavy Programmer
Python Heavy Programmer
 
Posts: 225
Joined: Tue Apr 07, 2009 2:54 pm

Re: Delegating method call by condition

Postby Azurin on Wed Mar 03, 2010 5:30 am

Yes.
But.
In your code object.__getattribute__ method will never be called. Before calling it all incoming parameters should be calculated. The step self.a will force recursion.
Azurin
Python Fan
Python Fan
 
Posts: 4
Joined: Sun Feb 28, 2010 8:53 am

Re: Delegating method call by condition

Postby targ on Fri Mar 05, 2010 3:20 am

That's true, unless condition also requires, or implies, that name != "a"; or something like:

Code: Select all
instance = object.__getattribute__(self, "a") if condition else self
return object.__getattribute__(instance, name)


But, depending on what condition actually is, there could be a better way to handle the whole thing.
targ
Python Heavy Programmer
Python Heavy Programmer
 
Posts: 225
Joined: Tue Apr 07, 2009 2:54 pm

Re: Delegating method call by condition

Postby avisser on Sat Mar 06, 2010 11:51 am

I don't get it.
Code: Select all
class A(object):
    def m1(self):
        pass
    def m2(self):
        pass

class B(object):
    def __init__(self):
        self.a = A()
    def m1(self):
        pass

b = B()
calling_b_method = b.m1()
calling_a_method_through_b = b.a.m1()
or do you mean calling a method of A() as if it were a method of B()?
Sometimes it helps explaining why you want do do something instead of just asking how to do it , this is just theoretical to me.
counselor: Fine, fine. But do you, do you have any qualifications?
Anchovy: Yes, I've got a hat.
counselor: A hat?
Anchovy: 'Yes, a hat. A lion taming hat. A hat with 'lion tamer' on it. I got it at Harrods. And it lights up saying 'lion tamer' in great big neon letters, so that you can tame them after dark when they're less stroppy.
avisser
Ultimate Python Hacker
Ultimate Python Hacker
 
Posts: 2540
Joined: Sat Oct 28, 2006 3:03 pm
Location: Holland

Re: Delegating method call by condition

Postby Azurin on Tue Mar 30, 2010 9:52 am

avisser,

Yes, the idea is to call A() methods as if they were B() methods.

I put more investigation to my task and find out that I could delegate method calls to A() only if they are not defined in B().
Simple inheritance is not suitable cause I SHOULD WRAP A() methods.
Here __getattr__ does it's job since called right before AttributeError.

I still haven't got time to test it a lot, but looks like working
Code: Select all
class A(object):
    def m1(self):
        pass
    def m2(self):
        pass

class B(object):
    def __init__(self):
        self.a = A()
    def __getattr__(self, name):
        return self._wrapped(name)
    def _wrapped(self, name):
        # do smth
        ret = getattr(self.a, name)
        # do smth
        return ret
Azurin
Python Fan
Python Fan
 
Posts: 4
Joined: Sun Feb 28, 2010 8:53 am


Return to Intermediate

Who is online

Users browsing this forum: No registered users and 1 guest

Sponsored by Dreamlink Web hosting and Traduzioni Rumeno Italiano and ASSP Deluxe for cPanel.