__call__ considered harmful or indispensable?

Neil Cerutti horpner at yahoo.com
Thu Aug 2 15:04:22 EDT 2007


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):
    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
This is not a book to be put down lightly. It should be thrown with great
force. --Dorothy Parker



More information about the Python-list mailing list