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