Can't define __call__ within __init__?
Steve Holden
steve at holdenweb.com
Thu Mar 11 08:30:12 EST 2010
Neal Becker wrote:
> 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.
>
This is a premature optimization. First, make it work. Then (if it
doesn't work fast enough) make it work faster.
regards
Steve
--
Steve Holden +1 571 484 6266 +1 800 494 3119
See PyCon Talks from Atlanta 2010 http://pycon.blip.tv/
Holden Web LLC http://www.holdenweb.com/
UPCOMING EVENTS: http://holdenweb.eventbrite.com/
More information about the Python-list
mailing list