Re: Overloading function calls

Guido.van.Rossum@cwi.nl
Wed, 08 Jun 1994 10:40:44 +0200

> > # don't know how to handle y
> > if hasattr(y, '__rbinop__'):
> > return y.__rbinop__(x)
> > else:
> > raise TypeError, etc
>
> Why not just raise a specific exception (e.g. OperatorError), and let
> the calling mechanism (i.e. compiler generated code / special opcode)
> handle the other case? It's simpler and maybe even faster.

The problem with using exceptions for such purposes is that if the
exception is raised unexpectedly somewhere inside the implementation
of __binop__ (which has no a priory reason to expect this nor to catch
it), the caller would mistakenly think that __binop__ wanted the RHS
dispatch version to be tried, while actually it was in deep trouble.

To improve just a little on the speed (maybe) I would rewrite it as
follows:

try:
f = y.__rbinop__
except AttributeError:
raise TypeError, etc
return f(x)

Note that hasattr actually tries getattr and catches the exception, so
that if the attribute exists we save another call to getattr, at the
cost of setting up a try-except handler in Python, which is a bit more
expensive than the 'if' version. If hasattr almost always fails, the
try-except version would be slower, but when it succeeds, try-except
is faster.

--Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl>
URL: <http://www.cwi.nl/cwi/people/Guido.van.Rossum.html>