This recipe allows for calling an unlimited chain of nonexistent attributes - every call is forwarded to a default method with attribute chain as argument.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | class MagicObject:
    def __call__(self,*args,**kwargs):
        return MagicObject.__dict__['_stop'](self,self.n,*args,**kwargs)
    def __getattr__(self,name):
        if name in ('__str__','__repr__'): return lambda:'instance of %s at %s' % (str(self.__class__),id(self))
        if not self.__dict__.has_key('n'):self.n=[]
        self.n.append(name)
        return self
    def _stop(self,n,*args,**kwargs):
        self.n=[]
        return self.default(n,*args,**kwargs)
    def default(self,n,*args,**kwargs):
        return 'stop',n,args,kwargs
#############################################################333
>>c=MagicObject()
>>x=c.beubeb.zzzzz(1,2,3,a='bbb')
>>print x
('stop', ['beubeb', 'zzzzz'], (1, 2, 3), {'a': 'bbb'})
 | 
I needed this to proxy XMLRPC calls - I wanted to have a local object which I could call as it was a remote object on the server, no matter how deep the attribute chain on the remote object is. I think it can be useful in many other situations, whenever you want to fake or proxy a more complicated object.
This recipe extends the __getattr__ method, so that you can call object.attr.subattr.method() and it all goes to the 'default' method, with a list of attributes in the chain as the first argument.
It works only for method calls - what I don't know is how to handle requests for nonexistent attributes. I just return self - maybe somebody smarter will come up with a solution how to pass them to the handler.

 Download
Download Copy to clipboard
Copy to clipboard
Give this a try if you want to capture requests for non-extant attributes or function calls:
class MagicObject2(MagicObject):
Notice the difference between this and whatever the original object might return:
You may find it easier to interpret the following when it comes time to make sense of what happened with this object at runtime:
{'beubeb': {'zzzzz': ((1, 2, 3), {'a': 'bbb'})}}
You would have to work from the inside outwards when making sense of this stuff but if you need this functionality it would make sense to use it.
Perhaps a few more lines of code might be requires to turn the MagicObject2 into something usable but you probably get the gist of where this is going from what I have posted above.
For more you can look at http://www.pypi.info <-- Might see something useful !