__getattr__ and others

Hans Nowak wurmy at earthlink.net
Wed Nov 13 01:15:10 EST 2002


Grzegorz Dostatni wrote:
> Hi.
> 
> I want to create an object that (at runtime) is called with an arbitrary
> function with arbitrary number of arguments.  Haveing this call it will
> forward it through xml-rpc to the server, execute it and return the
> results.
> 
> I am missing something simple - here is what I have:
> 
>     def calling(self, method="", *args, **kwargs):
>         print "calling method ", method
>         print "With arguments", args, kwargs
> 
>     def __getattr__(self, name):
>         return lambda s=self, m=name, *args, **kwargs: apply(s.calling,
> (m, ) + args, kwargs
> 
> This works as expected for (o is the instance of the object)
> 
> 1. o.hello = OK. Returns the lambda function.
> 2. o.hello(keyword="Argument") = OK. that works.
> 3. o.hello(3, keyword="Argument") = This does not work.
> 4. o.hello(3) = This does not work again.
> 
> I have to do something like o.hello(o, "hello", 3) to get what I want.

That's because if you do o.hello(3), s gets the value 3:

   lambda s=self, ...

rather than 'self'. Next you try to call s.calling, and since s is an integer 
now, it doesn't have a method 'calling'...

This does not occur with the keyword arguments, since they go to the **kwargs 
dict rather than overriding the s or m arguments.

> Does anyone have an idea how to make it more consistent with normal
> calling style?

This might work:

     def __getattr__(self, name):
         def temp(*args, **kwargs):
             self.calling(name, *args, **kwargs)
         return temp

HTH,

-- 
Hans (base64.decodestring('d3VybXlAZWFydGhsaW5rLm5ldA=='))
# decode for email address ;-)
The Pythonic Quarter:: http://www.awaretek.com/nowak/
Kaa:: http://www.awaretek.com/nowak/kaa.html




More information about the Python-list mailing list