__call__ considered harmful or indispensable?

Neil Cerutti horpner at yahoo.com
Thu Aug 2 15:06:49 EDT 2007


On 2007-08-02, Neil Cerutti <horpner at yahoo.com> wrote:
> On 2007-08-02, skip at pobox.com <skip at pobox.com> wrote:
>> I don't personally use __call__ methods in my classes, but I
>> have encountered it every now and then here at work in code
>> written by other people.  The other day I replaced __call__
>> with a more obvious method name, so now instead of executing
>>
>>     obj(foo, bar, baz)
>>
>> the code in question is
>>
>>     obj.execute(foo, bar, baz)
>>
>> In this case there was a bug.  Depending on inputs, sometimes
>> obj initialized to a class, sometimes an instance of that
>> class.  (I fixed that too while I was at it.)  The problem was
>> that the use of __call__ obscured the underlying bug by making
>> the instance as well as the class callable.
>>
>> In this particular case it was clearly unnecessary and just
>> obfuscated the code.  I'm wondering, are there some general
>> cases where __call__ methods of a user-defined class are simply
>> indispensable?
>
> In C++ they are called functors, and they are very useful as
> surrogate functions with state. I haven't seen them used in the
> same way in Python much, because Python has more immediate
> solutions to (most of) these problems.
>
> Here's a (somewhat goofy) example:
>
> class is_consecutive(object):
>   def __init__(self, seed, compare=operator.lt):

That was supposed to be operator.le, not lt. I forgot to repaste after
fixing that bug.

>     self.last_value = seed
>     self.compare = compare
>   def __call__(self, total, value):
>     if total is False:
>       return False
>     lv = self.last_value
>     self.last_value = value
>     return self.compare(lv, value):
>
> a = range(15)
>
>>>> reduce(is_consecutive(0), a)
> True
>>>> reduce(is_consecutive(0), a + [1,2])
> False
>
> It's been a while since I had to be in the STL mindset, so I
> couldn't think of a better example.
>


-- 
Neil Cerutti
The pastor will preach his farewell message, after which the choir will sing,
"Break Forth Into Joy." --Church Bulletin Blooper



More information about the Python-list mailing list