Can't define __call__ within __init__?

Neal Becker ndbecker2 at gmail.com
Thu Mar 11 07:56:59 EST 2010


Steven D'Aprano wrote:

> On Wed, 10 Mar 2010 08:12:14 -0500, Neal Becker wrote:
> 
>> Want to switch __call__ behavior.  Why doesn't this work?  What is the
>> correct way to write this?
>> 
>> class X (object):
>>     def __init__(self, i):
>>         if i == 0:
>>             def __call__ (self):
>>                 return 0
>>         else:
>>             def __call_ (self):
>>                 return 1
> 
> 
> Others have already pointed out that there are two reasons that won't
> work:
> 
> (1) you define __call__ as a local variable of the __init__ method which
> then disappears as soon as the __init__ method completes; and
> 
> (2) special methods like __call__ are only called on the class, not the
> instance, so you can't give each instance its own method.
> 
> 
> Perhaps the best way to solve this is to use delegation:
> 
> 
> def zero_returner():
>     return 0
> 
> def one_returner():
>     return 1
> 
> 
> class X (object):
>     def __init__(self, i):
>         if i == 0:
>             self.func = zero_returner
>         else:
>             self.func = one_returner
>     def __call__(self, *args, **kwargs):
>         return self.func(*args, **kwargs)
> 
> 
> zero_returner and one_returner can be any callable object, not
> necessarily a function.
> 
> Of course, all this assumes that your solution isn't even simpler:
> 
> class X (object):
>     def __init__(self, i):
>         self.i = i
>     def __call__(self):
>         return self.i
> 
> but I assume if it was that simple, you would have done that already.
> 
> 
> 
The example I showed was just a toy problem.  The real problem is
I expect to call a function many times, and I want to avoid the overhead of 
the 'if blah' everytime.




More information about the Python-list mailing list