[Python-Dev] Re: __op__ and __rop__ ([Python-checkins] CVS: python/dist/src PLAN.txt,1.10,1.11)
Guido van Rossum
guido@python.org
Fri, 28 Sep 2001 17:10:03 -0400
> Guido van Rossum wrote:
> >
> > + Treat all binary operators the same way as I just did for rich
> > + comparison: in a <op> b, if isinstance(b, type(a)), try b.__rop__(a)
> > + before trying a.__op__(b).
I didn't write the whole constraint: I should have added "if type(a)
is not type(b)" before "isinstance(b, type(a))".
> Some comments (could be that I'm misunderstanding your note...):
I hope so.
> - doesn't this cause an incompatibility to classic instances
> (__rop__ is fallback to __op__ not the other way around) ?
This change only apply to new-style classes.
> - it seems a huge performance loss to first check for __rop__
> (in my experience, __rop__ is only rarely implemented)
But that presumably means that you are only using your operators with
both operators being of the same type, and then __op__ is tried first.
> The classic scheme for this is documented in abstract.c:
>
> Calling scheme used for binary operations:
>
> v w Action
> -------------------------------------------------------------------
> new new v.op(v,w), w.op(v,w)
> new old v.op(v,w), coerce(v,w), v.op(v,w)
> old new w.op(v,w), coerce(v,w), v.op(v,w)
> old old coerce(v,w), v.op(v,w)
>
> Legend:
> -------
> * new == new style number
> * old == old style number
> * Action indicates the order in which operations are tried until either
> a valid result is produced or an error occurs.
>
> Most (if not all) Python builtin numeric types are new-style
> numbers. How would your plan fit into this picture ?
Because of the constraint isinstance(b, type(a)), this would only be
done for the "new new" case.
I have to admit I haven't done enough research to figure out if this
is feasible; in 2.2a4 it's implemented for rich comparisons only, so
you can have a look at the code there and play with it. For most
purposes, rich comparisons behave similar to new-style numeric
operations, except that the __op__ <--> __rop__ mapping is different
(see swapped_op).
--Guido van Rossum (home page: http://www.python.org/~guido/)