__call__ considered harmful or indispensable?

Bruno Desthuilliers bdesth.quelquechose at free.quelquepart.fr
Thu Aug 2 10:30:53 EDT 2007


skip at pobox.com a écrit :
> 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.

I don't quite get the point here. A concrete example would be welcome.

> 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?

"simply indispensable", I don't know. FWIW, most of the features of 
Python are not "simply indispensable" !-)

Most of what you can do with a callable instance can be done with 
closures (and is usually done so in FPLs), but given Python's OO nature, 
it's sometimes clearer and simpler to use callable instances than 
closures. One example that comes to mind is partial application that I 
first saw implemented with closures in Django, then as a class in PEP 
309's example. Another common use case is parameterized function 
decorators, that are often cleaner (IMHO) when implemented as classes 
with __call__ than with three levels of nested funcs. In both cases, 
closures and callables implementations are functionally equivalent, and 
this is transparent for user code, so it's mostly a matter of 
readability and personal preferences...

As far as I'm concerned, I do use __call__ "every know and then". 
Usually, because I had to pass a callable to some API and needed to 
parameterize it (IOW, ad-hoc partial application).



More information about the Python-list mailing list