Python Runtime Method Call Binding

Steven D'Aprano steve at REMOVE-THIS-cybersource.com.au
Thu Dec 4 10:48:33 EST 2008


On Thu, 04 Dec 2008 06:23:28 -0800, k3xji wrote:

> Hi,
> 
> Is there a way to hook a function call in python? I know __getattr__ is
> doing for variables, 

What do you mean "variables"? Do you mean attributes?


> it is giving us a chance before a field is
> initialized. 

What field? Is a field the same as a variable, or something else?


> Do we have same functionality for methods?

Yes, methods are attributes too, they are reached by the exact same 
mechanism as any other attribute.

Any object with a __call__ method can be called. Normally you create 
objects with a __call__ method by using def or lambda.

 
> Example:
> 
> class Foo(object):
>     def __call_method__(self, ...) # just pseudo
>         print 'A method is called in object...'
> 
> f = Foo()
> f.test_method()
> 
> I think you understand my point.

I wish I did. It might have helped if you actually showed the expected 
output of your "test_method", instead of expecting us to *guess* what you 
expect to happen. 

I'm going to guess what you mean, and show you one possible solution. 
Read it carefully: it shows three examples of __getattr__, starting from 
the simplest to the relatively complicated.


class Parrot(object):
    def __getattr__(self, name):
        if name == "colour":
            return "red"
        elif name == "talk":
            return lambda x: "Hi, I'm %s the talking parrot" % x
        elif name == "speak":
            class Birdy(object):
                def __init__(self, name):
                    self.name = name
                def __call__(self):
                    return "I'm the talking Parrot %s" % self.name
            return Birdy('Fred')
        else:
            raise AttributeError


And in use:

>>> p = Parrot()
>>> p.colour
'red'
>>> p.talk  # get the attribute "talk"
<function <lambda> at 0x81fab1c>
>>> 
>>> p.talk("Fred")  # call the attribute (method) "talk"
"Hi, I'm Fred the talking parrot"
>>> 
>>> p.speak
<__main__.Birdy object at 0x820076c>
>>> p.speak()
"I'm the talking Parrot Fred"


-- 
Steven



More information about the Python-list mailing list