__coerce__ vs. new-style classes
Hallvard B Furuseth
h.b.furuseth at usit.uio.no
Mon Aug 2 15:10:00 EDT 2004
John Roth wrote:
>"Hallvard B Furuseth" <h.b.furuseth at usit.uio.no> wrote in message
>news:HBF.20040802t150 at bombur.uio.no...
>> Why do new-style classes disable __coerce__()?
>> It seems cumbersome to have to write a whole set of methods (e.g.
>> __add__, __radd__, etc.) to get the same effect. Is there some way to
>> automatically generate those methods, or are we simply not supposed to
>> do coercion for some reason?
>
> I'm mildly confused by your example. __coerce__()
> converts the arguements to a common type, and then
> presumably requests that type to do the operation. That
> type might not be one of the two original types!
>
> It's not the same thing as the __op__, __rop__
> pair. That simply allows the right object to do the
> operation if the left object can't.
Yes:
>>> class DeferredIntType:
... def __init__(self, fetch, *args, **kwargs):
... def _fetch():
... v = long(fetch(*args, **kwargs))
... self.value = lambda: v
... return v
... self.value = _fetch
... def __long__(self): return self.value()
... def __int__(self): return int(self.value())
... def __str__(self): return str(self.value())
... def __coerce__(self, other):
... if isinstance(other, (int, long)):
... return type(other)(self.value()), other
...
>>> DeferredIntType(len, 'foobar') + 3
9
Can't add two of them without __add__ & co, but can do just about
everything else just by writing four small methods.
If I do include __add__ & co, they won't all have to coerce the
arguments 'by hand', or worry about what to do if they don't know
how to add the type of argument they received.
Without __coerce__, what should __add__(self, other) do if it doesn't
know how to add the arguments, but the other argument might know how?
It can't just call other.__radd__(self): That might give up and call
__add__ again.
In some cases it might help to call coerce() by hand, but I note the
ref manual says 'In Python 3.0, coercion will not be supported.'.
> The notion of type coercion makes a great deal of sense
> in languages such as C, where you have 8 integer types
> and 3 float types, but abstracting it out as a separate
> operation makes very little sense in Python, where you
> have 3 numeric types (int, long and float) and two string
> types (normal and unicode). The overhead of doing
> coercion as a separate operation simply doesn't make
> a lot of sense.
Well, I was thinking of types like the above, which emulate
numeric types. The case which got me started was one which
emulates the DECIMAL (or NUMERIC) SQL type in PgSQL.py.
> At least, that's the way I understand it. Section 3.3.8
> (Coercion Rules) of the 2.3 Language Reference gives
> the official reasons for moving away from doing coercion
> as part of operations. It simply got to complex to
> document properly.
I noticed that; I hadn't realized it was the argument for disabling
coercion completey.
--
Hallvard
More information about the Python-list
mailing list