It is no longer necessary to coerce both sides of an operator to the
same class or type. A class may still provide a __coerce__
method, but this method may return objects of different types or
classes if it feels like it. If no __coerce__
is defined, any
argument type or class is acceptable.
In order to make it possible to implement binary operators where the
right-hand side is a class instance but the left-hand side is not,
without using coercions, right-hand versions of all binary operators
may be defined. These have an `r' prepended to their name,
e.g. __radd__
.
For example, here's a very simple class for representing times. Times
are initialized from a number of seconds (like time.time()). Times
are printed like this: Wed Mar 15 12:28:48 1995
. Subtracting
two Times gives their difference in seconds. Adding or subtracting a
Time and a number gives a new Time. You can't add two times, nor can
you subtract a Time from a number.
import time class Time: def __init__(self, seconds): self.seconds = seconds def __repr__(self): return time.ctime(self.seconds) def __add__(self, x): return Time(self.seconds + x) __radd__ = __add__ # support for x+t def __sub__(self, x): if hasattr(x, 'seconds'): # test if x could be a Time return self.seconds - x.seconds else: return self.seconds - x now = Time(time.time()) tomorrow = 24*3600 + now yesterday = now - today print tomorrow - yesterday # prints 172800