Indeed, special methods are looked up on the type and you cannot set them on the instance.
If you want to not always support .__add__
return the NotImplemented
singleton:
class test:
def __init__(self, overload):
self.overload = overload
def __add__(self, other):
if not self.overload:
return NotImplemented
print("Ok")
Returning NotImplemented
from a rich comparison method makes Python behave as if there was no such method; usually this is used to signal that the type of other
isn't supported, but you are free to return it when you don't want to support the operation just now.
Note that Python will still try the reverse operation; for test() + something
, Python first tries test().__add__(something)
, then something.__radd__(test())
is called if the first operation returned NotImplemented
. If the latter doesn't exist or also returns NotImplemented
, a TypeError
is raised.
Demo:
>>> class test:
... def __init__(self, overload):
... self.overload = overload
... def __add__(self, other):
... if not self.overload:
... return NotImplemented
... print("Ok")
...
>>> test(False) + 1
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'instance' and 'int'
>>> test(True) + 1
Ok